17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 569bb4bb4Scarlsonj * Common Development and Distribution License (the "License"). 669bb4bb4Scarlsonj * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 2265c8f1c0Smeem * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 2503aa4c8dSSebastien Roy /* 2603aa4c8dSSebastien Roy * Copyright (c) 2013, 2015 by Delphix. All rights reserved. 2778a2e113SAndy Fiddaman * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. 2803aa4c8dSSebastien Roy */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #ifndef _DHCPAGENT_IPC_H 317c478bd9Sstevel@tonic-gate #define _DHCPAGENT_IPC_H 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <sys/socket.h> 3465c8f1c0Smeem #include <net/if.h> /* LIFNAMSIZ */ 357c478bd9Sstevel@tonic-gate #include <stddef.h> 367c478bd9Sstevel@tonic-gate #include <sys/types.h> 377c478bd9Sstevel@tonic-gate #include <sys/time.h> 387c478bd9Sstevel@tonic-gate #include <netinet/dhcp.h> 397c478bd9Sstevel@tonic-gate #include <dhcp_impl.h> 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /* 427c478bd9Sstevel@tonic-gate * dhcpagent_ipc.[ch] comprise the interface used to perform 437c478bd9Sstevel@tonic-gate * interprocess communication with the agent. see dhcpagent_ipc.c for 447c478bd9Sstevel@tonic-gate * documentation on how to use the exported functions. 457c478bd9Sstevel@tonic-gate */ 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate #ifdef __cplusplus 487c478bd9Sstevel@tonic-gate extern "C" { 497c478bd9Sstevel@tonic-gate #endif 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #define DHCP_AGENT_PATH "/sbin/dhcpagent" 527c478bd9Sstevel@tonic-gate #define DHCP_IPC_LISTEN_BACKLOG 30 537c478bd9Sstevel@tonic-gate #define IPPORT_DHCPAGENT 4999 54d04ccbb3Scarlsonj #define DHCP_IPC_MAX_WAIT 15 /* max seconds to wait to start agent */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate /* 577c478bd9Sstevel@tonic-gate * return values which should be used by programs which talk to the 587c478bd9Sstevel@tonic-gate * agent (for uniformity). 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate #define DHCP_EXIT_SUCCESS 0 627c478bd9Sstevel@tonic-gate #define DHCP_EXIT_FAILURE 2 637c478bd9Sstevel@tonic-gate #define DHCP_EXIT_BADARGS 3 647c478bd9Sstevel@tonic-gate #define DHCP_EXIT_TIMEOUT 4 657c478bd9Sstevel@tonic-gate #define DHCP_EXIT_SYSTEM 6 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* 687c478bd9Sstevel@tonic-gate * opaque types for requests and replies. users of this api do not 697c478bd9Sstevel@tonic-gate * need to understand their contents. 707c478bd9Sstevel@tonic-gate */ 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate typedef struct dhcp_ipc_request dhcp_ipc_request_t; 737c478bd9Sstevel@tonic-gate typedef struct dhcp_ipc_reply dhcp_ipc_reply_t; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate /* payloads that can be passed in a request or reply */ 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate typedef enum { 787c478bd9Sstevel@tonic-gate DHCP_TYPE_OPTION, 797c478bd9Sstevel@tonic-gate DHCP_TYPE_STATUS, 807c478bd9Sstevel@tonic-gate DHCP_TYPE_OPTNUM, 817c478bd9Sstevel@tonic-gate DHCP_TYPE_NONE 827c478bd9Sstevel@tonic-gate } dhcp_data_type_t; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * requests that can be sent to the agent 867c478bd9Sstevel@tonic-gate * 877c478bd9Sstevel@tonic-gate * code in dhcpagent relies on the numeric values of these 887c478bd9Sstevel@tonic-gate * requests -- but there's no sane reason to change them anyway. 89d04ccbb3Scarlsonj * 90cfb9c9abScarlsonj * If any commands are changed, added, or removed, see the ipc_typestr[] 91d04ccbb3Scarlsonj * array in dhcpagent_ipc.c. 927c478bd9Sstevel@tonic-gate */ 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate typedef enum { 957c478bd9Sstevel@tonic-gate DHCP_DROP, DHCP_EXTEND, DHCP_PING, DHCP_RELEASE, 9678a2e113SAndy Fiddaman DHCP_START, DHCP_STATUS, DHCP_INFORM, DHCP_GET_TAG, 977c478bd9Sstevel@tonic-gate DHCP_NIPC, /* number of supported requests */ 98d04ccbb3Scarlsonj DHCP_PRIMARY = 0x100, 99d04ccbb3Scarlsonj DHCP_V6 = 0x200 1007c478bd9Sstevel@tonic-gate } dhcp_ipc_type_t; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* structure passed with the DHCP_GET_TAG request */ 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate typedef struct { 105d04ccbb3Scarlsonj uint_t category; 106d04ccbb3Scarlsonj uint_t code; 107d04ccbb3Scarlsonj uint_t size; 1087c478bd9Sstevel@tonic-gate } dhcp_optnum_t; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate #define DHCP_IPC_CMD(type) ((type) & 0x00ff) 1117c478bd9Sstevel@tonic-gate #define DHCP_IPC_FLAGS(type) ((type) & 0xff00) 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /* special timeout values for dhcp_ipc_make_request() */ 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate #define DHCP_IPC_WAIT_FOREVER (-1) 1167c478bd9Sstevel@tonic-gate #define DHCP_IPC_WAIT_DEFAULT (-2) 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate /* 1197c478bd9Sstevel@tonic-gate * errors that can be returned from the provided functions. 1207c478bd9Sstevel@tonic-gate * note: keep in sync with dhcp_ipc_strerror() 1217c478bd9Sstevel@tonic-gate */ 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate enum { 124d04ccbb3Scarlsonj /* System call errors must be kept contiguous */ 1257c478bd9Sstevel@tonic-gate DHCP_IPC_SUCCESS, DHCP_IPC_E_SOCKET, DHCP_IPC_E_FCNTL, 1267c478bd9Sstevel@tonic-gate DHCP_IPC_E_READ, DHCP_IPC_E_ACCEPT, DHCP_IPC_E_CLOSE, 1277c478bd9Sstevel@tonic-gate DHCP_IPC_E_BIND, DHCP_IPC_E_LISTEN, DHCP_IPC_E_MEMORY, 128d04ccbb3Scarlsonj DHCP_IPC_E_CONNECT, DHCP_IPC_E_WRITEV, DHCP_IPC_E_POLL, 129d04ccbb3Scarlsonj 130d04ccbb3Scarlsonj /* All others follow */ 131d04ccbb3Scarlsonj DHCP_IPC_E_TIMEOUT, DHCP_IPC_E_SRVFAILED, DHCP_IPC_E_EOF, 1327c478bd9Sstevel@tonic-gate DHCP_IPC_E_INVIF, DHCP_IPC_E_INT, DHCP_IPC_E_PERM, 1337c478bd9Sstevel@tonic-gate DHCP_IPC_E_OUTSTATE, DHCP_IPC_E_PEND, DHCP_IPC_E_BOOTP, 1347c478bd9Sstevel@tonic-gate DHCP_IPC_E_CMD_UNKNOWN, DHCP_IPC_E_UNKIF, DHCP_IPC_E_PROTO, 1357c478bd9Sstevel@tonic-gate DHCP_IPC_E_FAILEDIF, DHCP_IPC_E_NOPRIMARY, DHCP_IPC_E_DOWNIF, 136d04ccbb3Scarlsonj DHCP_IPC_E_NOIPIF, DHCP_IPC_E_NOVALUE, DHCP_IPC_E_RUNNING 1377c478bd9Sstevel@tonic-gate }; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* 1407c478bd9Sstevel@tonic-gate * low-level public dhcpagent ipc functions -- these are for use by 1417c478bd9Sstevel@tonic-gate * programs that need to communicate with the dhcpagent. these will 1427c478bd9Sstevel@tonic-gate * remain relatively stable. 1437c478bd9Sstevel@tonic-gate */ 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate extern const char *dhcp_ipc_strerror(int); 1467c478bd9Sstevel@tonic-gate extern dhcp_ipc_request_t *dhcp_ipc_alloc_request(dhcp_ipc_type_t, const char *, 147d04ccbb3Scarlsonj const void *, uint32_t, dhcp_data_type_t); 1487c478bd9Sstevel@tonic-gate extern void *dhcp_ipc_get_data(dhcp_ipc_reply_t *, size_t *, 1497c478bd9Sstevel@tonic-gate dhcp_data_type_t *); 1507c478bd9Sstevel@tonic-gate extern int dhcp_ipc_make_request(dhcp_ipc_request_t *, 1517c478bd9Sstevel@tonic-gate dhcp_ipc_reply_t **, int32_t); 152d04ccbb3Scarlsonj extern const char *dhcp_ipc_type_to_string(dhcp_ipc_type_t); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate /* 1557c478bd9Sstevel@tonic-gate * high-level public dhcpagent ipc functions 1567c478bd9Sstevel@tonic-gate */ 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate extern int dhcp_ipc_getinfo(dhcp_optnum_t *, DHCP_OPT **, int32_t); 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate /* 1617c478bd9Sstevel@tonic-gate * private dhcpagent ipc "server side" functions -- these are only for 162*bbf21555SRichard Lowe * use by dhcpagent(8) and are subject to change. 1637c478bd9Sstevel@tonic-gate */ 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate extern int dhcp_ipc_init(int *); 1667c478bd9Sstevel@tonic-gate extern int dhcp_ipc_accept(int, int *, int *); 1677c478bd9Sstevel@tonic-gate extern int dhcp_ipc_recv_request(int, dhcp_ipc_request_t **, int); 168d04ccbb3Scarlsonj extern dhcp_ipc_reply_t *dhcp_ipc_alloc_reply(dhcp_ipc_request_t *, int, 169d04ccbb3Scarlsonj const void *, uint32_t, dhcp_data_type_t); 1707c478bd9Sstevel@tonic-gate extern int dhcp_ipc_send_reply(int, dhcp_ipc_reply_t *); 1717c478bd9Sstevel@tonic-gate extern int dhcp_ipc_close(int); 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * values for if_state in the dhcp_status_t 1757c478bd9Sstevel@tonic-gate * 1767c478bd9Sstevel@tonic-gate * code in this library and dhcpagent rely on the numeric values of these 1777c478bd9Sstevel@tonic-gate * requests -- but there's no sane reason to change them anyway. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate typedef enum { 1817c478bd9Sstevel@tonic-gate INIT, /* nothing done yet */ 1827c478bd9Sstevel@tonic-gate SELECTING, /* sent DISCOVER, waiting for OFFERs */ 1837c478bd9Sstevel@tonic-gate REQUESTING, /* sent REQUEST, waiting for ACK/NAK */ 18469bb4bb4Scarlsonj PRE_BOUND, /* have ACK, setting up interface */ 1857c478bd9Sstevel@tonic-gate BOUND, /* have a valid lease */ 1867c478bd9Sstevel@tonic-gate RENEWING, /* have lease, but trying to renew */ 1877c478bd9Sstevel@tonic-gate REBINDING, /* have lease, but trying to rebind */ 1887c478bd9Sstevel@tonic-gate INFORMATION, /* sent INFORM, received ACK */ 189d04ccbb3Scarlsonj INIT_REBOOT, /* attempt to use cached ACK/Reply */ 1907c478bd9Sstevel@tonic-gate ADOPTING, /* attempting to adopt */ 1917c478bd9Sstevel@tonic-gate INFORM_SENT, /* sent INFORM, awaiting ACK */ 192d04ccbb3Scarlsonj DECLINING, /* sent v6 Decline, awaiting Reply */ 193d04ccbb3Scarlsonj RELEASING, /* sent v6 Release, awaiting Reply */ 1947c478bd9Sstevel@tonic-gate DHCP_NSTATES /* total number of states */ 1957c478bd9Sstevel@tonic-gate } DHCPSTATE; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate /* values for if_dflags in the dhcp_status_t */ 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate #define DHCP_IF_PRIMARY 0x0100 /* interface is primary interface */ 2007c478bd9Sstevel@tonic-gate #define DHCP_IF_BUSY 0x0200 /* asynchronous command pending */ 2017c478bd9Sstevel@tonic-gate #define DHCP_IF_BOOTP 0x0400 /* interface is using bootp */ 2027c478bd9Sstevel@tonic-gate #define DHCP_IF_REMOVED 0x0800 /* interface is going away */ 2037c478bd9Sstevel@tonic-gate #define DHCP_IF_FAILED 0x1000 /* interface configuration problem */ 204d04ccbb3Scarlsonj #define DHCP_IF_V6 0x2000 /* DHCPv6 interface */ 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /* 2077c478bd9Sstevel@tonic-gate * structure passed with the DHCP_STATUS replies 2087c478bd9Sstevel@tonic-gate * 2097c478bd9Sstevel@tonic-gate * when parsing a dhcp_status_t, `version' should always be checked 2107c478bd9Sstevel@tonic-gate * if there is a need to access any fields which were not defined in 2117c478bd9Sstevel@tonic-gate * version 1 of this structure. 2127c478bd9Sstevel@tonic-gate * 2137c478bd9Sstevel@tonic-gate * as new fields are added to the dhcp_status_t, they should be 2147c478bd9Sstevel@tonic-gate * appended to the structure and the version number incremented. 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate typedef struct dhcp_status { 2187c478bd9Sstevel@tonic-gate uint8_t version; /* version of this structure */ 2197c478bd9Sstevel@tonic-gate 22065c8f1c0Smeem char if_name[LIFNAMSIZ]; 2217c478bd9Sstevel@tonic-gate DHCPSTATE if_state; /* state of interface; see above */ 2227c478bd9Sstevel@tonic-gate 22378a2e113SAndy Fiddaman /* 22478a2e113SAndy Fiddaman * We use int64_t here so that the structure is the same in both 22578a2e113SAndy Fiddaman * 32 and 64-bit, since it is passed via IPC. 22678a2e113SAndy Fiddaman * Once everything that uses this is 64-bit, these could be changed 22778a2e113SAndy Fiddaman * to time_t. 22878a2e113SAndy Fiddaman */ 22978a2e113SAndy Fiddaman int64_t if_began; /* time lease began (absolute) */ 23078a2e113SAndy Fiddaman int64_t if_t1; /* renewing time (absolute) */ 23178a2e113SAndy Fiddaman int64_t if_t2; /* rebinding time (absolute) */ 23278a2e113SAndy Fiddaman int64_t if_lease; /* lease expiration time (absolute) */ 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate uint16_t if_dflags; /* DHCP flags on this if; see above */ 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * these three fields are initially zero, and get incremented 2387c478bd9Sstevel@tonic-gate * as if_state goes from INIT -> BOUND (or INIT -> 2397c478bd9Sstevel@tonic-gate * INFORMATION). if and when the interface moves to the 2407c478bd9Sstevel@tonic-gate * RENEWING state, these fields are reset, so they always 2417c478bd9Sstevel@tonic-gate * either indicate the number of packets sent, received, and 2427c478bd9Sstevel@tonic-gate * declined while obtaining the current lease (if BOUND), or 2437c478bd9Sstevel@tonic-gate * the number of packets sent, received, and declined while 2447c478bd9Sstevel@tonic-gate * attempting to obtain a future lease (if any other state). 2457c478bd9Sstevel@tonic-gate */ 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate uint32_t if_sent; 2487c478bd9Sstevel@tonic-gate uint32_t if_recv; 2497c478bd9Sstevel@tonic-gate uint32_t if_bad_offers; 2507c478bd9Sstevel@tonic-gate } dhcp_status_t; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate #define DHCP_STATUS_VER 1 /* current version of dhcp_status_t */ 2537c478bd9Sstevel@tonic-gate #define DHCP_STATUS_VER1_SIZE (offsetof(dhcp_status_t, if_bad_offers) + \ 2547c478bd9Sstevel@tonic-gate sizeof (uint32_t)) 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate /* 2577c478bd9Sstevel@tonic-gate * the remainder of this file contains implementation-specific 2587c478bd9Sstevel@tonic-gate * artifacts which may change. note that a `dhcp_ipc_request_t' and a 2597c478bd9Sstevel@tonic-gate * `dhcp_ipc_reply_t' are incomplete types as far as consumers of this 2607c478bd9Sstevel@tonic-gate * api are concerned. use these details at your own risk. 2617c478bd9Sstevel@tonic-gate */ 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate typedef hrtime_t dhcp_ipc_id_t; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate /* 2667c478bd9Sstevel@tonic-gate * note: the first 4 fields of the dhcp_ipc_request_t and dhcp_ipc_reply_t 2677c478bd9Sstevel@tonic-gate * are intentionally identical; code in dhcpagent_ipc.c counts on it! 26803aa4c8dSSebastien Roy * 26903aa4c8dSSebastien Roy * we pack these structs to ensure that their lengths will be identical between 27003aa4c8dSSebastien Roy * 32-bit and 64-bit executables. 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate 27303aa4c8dSSebastien Roy #pragma pack(4) 27403aa4c8dSSebastien Roy 2757c478bd9Sstevel@tonic-gate struct dhcp_ipc_request { 2767c478bd9Sstevel@tonic-gate dhcp_ipc_type_t message_type; /* type of request */ 2777c478bd9Sstevel@tonic-gate dhcp_ipc_id_t ipc_id; /* per-socket unique request id */ 2787c478bd9Sstevel@tonic-gate dhcp_data_type_t data_type; /* type of payload */ 2797c478bd9Sstevel@tonic-gate uint32_t data_length; /* size of actual data in the buffer */ 28065c8f1c0Smeem char ifname[LIFNAMSIZ]; 2817c478bd9Sstevel@tonic-gate int32_t timeout; /* timeout in seconds */ 2827c478bd9Sstevel@tonic-gate uchar_t buffer[1]; /* dynamically extended */ 2837c478bd9Sstevel@tonic-gate }; 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate struct dhcp_ipc_reply { 2867c478bd9Sstevel@tonic-gate dhcp_ipc_type_t message_type; /* same message type as request */ 2877c478bd9Sstevel@tonic-gate dhcp_ipc_id_t ipc_id; /* same id as request */ 2887c478bd9Sstevel@tonic-gate dhcp_data_type_t data_type; /* type of payload */ 2897c478bd9Sstevel@tonic-gate uint32_t data_length; /* size of actual data in the buffer */ 2907c478bd9Sstevel@tonic-gate uint32_t return_code; /* did the request succeed? */ 2917c478bd9Sstevel@tonic-gate uchar_t buffer[1]; /* dynamically extended */ 2927c478bd9Sstevel@tonic-gate }; 2937c478bd9Sstevel@tonic-gate 29403aa4c8dSSebastien Roy #pragma pack() 2957c478bd9Sstevel@tonic-gate 29603aa4c8dSSebastien Roy #define DHCP_IPC_REPLY_SIZE offsetof(dhcp_ipc_reply_t, buffer) 29703aa4c8dSSebastien Roy #define DHCP_IPC_REQUEST_SIZE offsetof(dhcp_ipc_request_t, buffer) 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate #define DHCP_IPC_DEFAULT_WAIT 120 /* seconds */ 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate #ifdef __cplusplus 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate #endif 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate #endif /* _DHCPAGENT_IPC_H */ 306