10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
22*1254Smeem 
230Sstevel@tonic-gate /*
24*1254Smeem  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
250Sstevel@tonic-gate  * Use is subject to license terms.
260Sstevel@tonic-gate  */
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #ifndef _LIBINETUTIL_H
290Sstevel@tonic-gate #define	_LIBINETUTIL_H
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
320Sstevel@tonic-gate 
330Sstevel@tonic-gate /*
34*1254Smeem  * Contains SMI-private API for general Internet functionality
350Sstevel@tonic-gate  */
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #ifdef	__cplusplus
380Sstevel@tonic-gate extern "C" {
390Sstevel@tonic-gate #endif
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #include <netinet/inetutil.h>
420Sstevel@tonic-gate #include <sys/types.h>
430Sstevel@tonic-gate #include <sys/socket.h>
440Sstevel@tonic-gate #include <netinet/in.h>
450Sstevel@tonic-gate #include <net/if.h>
460Sstevel@tonic-gate 
470Sstevel@tonic-gate #if !defined(_KERNEL) && !defined(_BOOT)
480Sstevel@tonic-gate 
490Sstevel@tonic-gate #define	IFSP_MAXMODS	9	/* Max modules that can be pushed on if */
500Sstevel@tonic-gate 
510Sstevel@tonic-gate typedef struct {
520Sstevel@tonic-gate 	uint_t		ifsp_ppa;	/* Physical Point of Attachment */
530Sstevel@tonic-gate 	uint_t		ifsp_lun;	/* Logical Unit number */
540Sstevel@tonic-gate 	boolean_t	ifsp_lunvalid;	/* TRUE if lun is valid */
550Sstevel@tonic-gate 	int		ifsp_modcnt;	/* Number of modules to be pushed */
560Sstevel@tonic-gate 	char		ifsp_devnm[LIFNAMSIZ];	/* only the device name */
570Sstevel@tonic-gate 	char		ifsp_mods[IFSP_MAXMODS][LIFNAMSIZ]; /* table of mods */
580Sstevel@tonic-gate } ifspec_t;
590Sstevel@tonic-gate 
600Sstevel@tonic-gate extern boolean_t ifparse_ifspec(const char *, ifspec_t *);
610Sstevel@tonic-gate extern void get_netmask4(const struct in_addr *, struct in_addr *);
620Sstevel@tonic-gate 
630Sstevel@tonic-gate /*
64*1254Smeem  * Extended version of the classic BSD ifaddrlist() interface:
65*1254Smeem  *
66*1254Smeem  *    int ifaddrlist(struct ifaddrlist **addrlistp, int af, char *errbuf);
67*1254Smeem  *
68*1254Smeem  * 	* addrlistp: Upon success, ifaddrlist() sets *addrlistp to a
69*1254Smeem  *	  dynamically-allocated array of addresses.
70*1254Smeem  *
71*1254Smeem  *	* af: Either AF_INET to obtain IPv4 addresses, or AF_INET6 to
72*1254Smeem  *	  obtain IPv6 addresses.
73*1254Smeem  *
74*1254Smeem  *	* errbuf: A caller-supplied buffer of ERRBUFSIZE.  Upon failure,
75*1254Smeem  *	  provides the reason for the failure.
76*1254Smeem  *
77*1254Smeem  * Upon success, ifaddrlist() returns the number of addresses in the array
78*1254Smeem  * pointed to by `addrlistp'.  If the count is 0, then `addrlistp' is NULL.
79*1254Smeem  */
80*1254Smeem union any_in_addr {
81*1254Smeem 	struct in6_addr	addr6;
82*1254Smeem 	struct in_addr	addr;
83*1254Smeem };
84*1254Smeem 
85*1254Smeem struct ifaddrlist {
86*1254Smeem 	int		index;			/* interface index */
87*1254Smeem 	union any_in_addr addr;			/* interface address */
88*1254Smeem 	char		device[LIFNAMSIZ + 1];	/* interface name */
89*1254Smeem 	uint64_t	flags;			/* interface flags */
90*1254Smeem };
91*1254Smeem 
92*1254Smeem #define	ERRBUFSIZE 128			/* expected size of third argument */
93*1254Smeem 
94*1254Smeem extern int ifaddrlist(struct ifaddrlist **, int, char *);
95*1254Smeem 
96*1254Smeem /*
970Sstevel@tonic-gate  * Timer queues
980Sstevel@tonic-gate  *
990Sstevel@tonic-gate  * timer queues are a facility for managing timeouts in unix.  in the
1000Sstevel@tonic-gate  * event driven model, unix provides us with poll(2)/select(3C), which
1010Sstevel@tonic-gate  * allow us to coordinate waiting on multiple descriptors with an
1020Sstevel@tonic-gate  * optional timeout.  however, often (as is the case with the DHCP
1030Sstevel@tonic-gate  * agent), we want to manage multiple independent timeouts (say, one
1040Sstevel@tonic-gate  * for waiting for an OFFER to come back from a server in response to
1050Sstevel@tonic-gate  * a DISCOVER sent out on one interface, and another for waiting for
1060Sstevel@tonic-gate  * the T1 time on another interface).  timer queues allow us to do
1070Sstevel@tonic-gate  * this in the event-driven model.
1080Sstevel@tonic-gate  *
1090Sstevel@tonic-gate  * note that timer queues do not in and of themselves provide the
1100Sstevel@tonic-gate  * event driven model (for instance, there is no handle_events()
1110Sstevel@tonic-gate  * routine).  they merely provide the hooks to support multiple
1120Sstevel@tonic-gate  * independent timeouts.  this is done for both simplicity and
1130Sstevel@tonic-gate  * applicability (for instance, while one approach would be to use
1140Sstevel@tonic-gate  * this timer queue with poll(2), another one would be to use SIGALRM
1150Sstevel@tonic-gate  * to wake up periodically, and then process all the expired timers.)
1160Sstevel@tonic-gate  */
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate typedef struct iu_timer_queue iu_tq_t;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate /*
1210Sstevel@tonic-gate  * a iu_timer_id_t refers to a given timer.  its value should not be
1220Sstevel@tonic-gate  * interpreted by the interface consumer.  it is a signed arithmetic
1230Sstevel@tonic-gate  * type, and no valid iu_timer_id_t has the value `-1'.
1240Sstevel@tonic-gate  */
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate typedef int iu_timer_id_t;
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate #define	IU_TIMER_ID_MAX	1024	/* max number of concurrent timers */
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate /*
1310Sstevel@tonic-gate  * a iu_tq_callback_t is a function that is called back in response to a
1320Sstevel@tonic-gate  * timer expiring.  it may then carry out any necessary work,
1330Sstevel@tonic-gate  * including rescheduling itself for callback or scheduling /
1340Sstevel@tonic-gate  * cancelling other timers.  the `void *' argument is the same value
1350Sstevel@tonic-gate  * that was passed into iu_schedule_timer(), and if it is dynamically
1360Sstevel@tonic-gate  * allocated, it is the callback's responsibility to know that, and to
1370Sstevel@tonic-gate  * free it.
1380Sstevel@tonic-gate  */
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate typedef void	iu_tq_callback_t(iu_tq_t *, void *);
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate iu_tq_t		*iu_tq_create(void);
1430Sstevel@tonic-gate void		iu_tq_destroy(iu_tq_t *);
1440Sstevel@tonic-gate iu_timer_id_t	iu_schedule_timer(iu_tq_t *, uint32_t, iu_tq_callback_t *,
1450Sstevel@tonic-gate 		    void *);
1460Sstevel@tonic-gate iu_timer_id_t	iu_schedule_timer_ms(iu_tq_t *, uint64_t, iu_tq_callback_t *,
1470Sstevel@tonic-gate 		    void *);
1480Sstevel@tonic-gate int		iu_adjust_timer(iu_tq_t *, iu_timer_id_t, uint32_t);
1490Sstevel@tonic-gate int		iu_cancel_timer(iu_tq_t *, iu_timer_id_t, void **);
1500Sstevel@tonic-gate int		iu_expire_timers(iu_tq_t *);
1510Sstevel@tonic-gate int		iu_earliest_timer(iu_tq_t *);
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate /*
1540Sstevel@tonic-gate  * Event Handler
1550Sstevel@tonic-gate  *
1560Sstevel@tonic-gate  * an event handler is an object-oriented "wrapper" for select(3C) /
1570Sstevel@tonic-gate  * poll(2), aimed to make the event demultiplexing system calls easier
1580Sstevel@tonic-gate  * to use and provide a generic reusable component.  instead of
1590Sstevel@tonic-gate  * applications directly using select(3C) / poll(2), they register
1600Sstevel@tonic-gate  * events that should be received with the event handler, providing a
1610Sstevel@tonic-gate  * callback function to call when the event occurs.  they then call
1620Sstevel@tonic-gate  * iu_handle_events() to wait and callback the registered functions
1630Sstevel@tonic-gate  * when events occur.  also called a `reactor'.
1640Sstevel@tonic-gate  */
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate typedef struct iu_event_handler iu_eh_t;
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate /*
1690Sstevel@tonic-gate  * an iu_event_id_t refers to a given event.  its value should not be
1700Sstevel@tonic-gate  * interpreted by the interface consumer.  it is a signed arithmetic
1710Sstevel@tonic-gate  * type, and no valid iu_event_id_t has the value `-1'.
1720Sstevel@tonic-gate  */
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate typedef int iu_event_id_t;
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate /*
1770Sstevel@tonic-gate  * an iu_eh_callback_t is a function that is called back in response to
1780Sstevel@tonic-gate  * an event occurring.  it may then carry out any work necessary in
1790Sstevel@tonic-gate  * response to the event.  it receives the file descriptor upon which
1800Sstevel@tonic-gate  * the event occurred, a bit array of events that occurred (the same
1810Sstevel@tonic-gate  * array used as the revents by poll(2)), and its context through the
1820Sstevel@tonic-gate  * `void *' that was originally passed into iu_register_event().
1830Sstevel@tonic-gate  *
1840Sstevel@tonic-gate  * NOTE: the same descriptor may not be registered multiple times for
1850Sstevel@tonic-gate  * different callbacks.  if this behavior is desired, either use dup(2)
1860Sstevel@tonic-gate  * to get a unique descriptor, or demultiplex in the callback function
1870Sstevel@tonic-gate  * based on the events.
1880Sstevel@tonic-gate  */
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate typedef void	iu_eh_callback_t(iu_eh_t *, int, short, iu_event_id_t, void *);
1910Sstevel@tonic-gate typedef void	iu_eh_sighandler_t(iu_eh_t *, int, void *);
1920Sstevel@tonic-gate typedef boolean_t iu_eh_shutdown_t(iu_eh_t *, void *);
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate iu_eh_t		*iu_eh_create(void);
1950Sstevel@tonic-gate void		iu_eh_destroy(iu_eh_t *);
1960Sstevel@tonic-gate iu_event_id_t	iu_register_event(iu_eh_t *, int, short, iu_eh_callback_t *,
1970Sstevel@tonic-gate 		    void *);
1980Sstevel@tonic-gate int		iu_unregister_event(iu_eh_t *, iu_event_id_t, void **);
1990Sstevel@tonic-gate int		iu_handle_events(iu_eh_t *, iu_tq_t *);
2000Sstevel@tonic-gate void		iu_stop_handling_events(iu_eh_t *, unsigned int,
2010Sstevel@tonic-gate 		    iu_eh_shutdown_t *, void *);
2020Sstevel@tonic-gate int		iu_eh_register_signal(iu_eh_t *, int, iu_eh_sighandler_t *,
2030Sstevel@tonic-gate 		    void *);
2040Sstevel@tonic-gate int		iu_eh_unregister_signal(iu_eh_t *, int, void **);
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate #endif	/* !defined(_KERNEL) && !defined(_BOOT) */
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate #ifdef	__cplusplus
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate #endif
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate #endif	/* !_LIBINETUTIL_H */
213