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 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #ifndef _LIBINETUTIL_H 29 #define _LIBINETUTIL_H 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * Contains SMI-private API for general Internet functionality 35 */ 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 #include <netinet/inetutil.h> 42 #include <sys/types.h> 43 #include <sys/socket.h> 44 #include <netinet/in.h> 45 #include <net/if.h> 46 47 #if !defined(_KERNEL) && !defined(_BOOT) 48 49 #define IFSP_MAXMODS 9 /* Max modules that can be pushed on if */ 50 51 typedef struct { 52 uint_t ifsp_ppa; /* Physical Point of Attachment */ 53 uint_t ifsp_lun; /* Logical Unit number */ 54 boolean_t ifsp_lunvalid; /* TRUE if lun is valid */ 55 int ifsp_modcnt; /* Number of modules to be pushed */ 56 char ifsp_devnm[LIFNAMSIZ]; /* only the device name */ 57 char ifsp_mods[IFSP_MAXMODS][LIFNAMSIZ]; /* table of mods */ 58 } ifspec_t; 59 60 extern boolean_t ifparse_ifspec(const char *, ifspec_t *); 61 extern void get_netmask4(const struct in_addr *, struct in_addr *); 62 63 /* 64 * Extended version of the classic BSD ifaddrlist() interface: 65 * 66 * int ifaddrlist(struct ifaddrlist **addrlistp, int af, char *errbuf); 67 * 68 * * addrlistp: Upon success, ifaddrlist() sets *addrlistp to a 69 * dynamically-allocated array of addresses. 70 * 71 * * af: Either AF_INET to obtain IPv4 addresses, or AF_INET6 to 72 * obtain IPv6 addresses. 73 * 74 * * errbuf: A caller-supplied buffer of ERRBUFSIZE. Upon failure, 75 * provides the reason for the failure. 76 * 77 * Upon success, ifaddrlist() returns the number of addresses in the array 78 * pointed to by `addrlistp'. If the count is 0, then `addrlistp' is NULL. 79 */ 80 union any_in_addr { 81 struct in6_addr addr6; 82 struct in_addr addr; 83 }; 84 85 struct ifaddrlist { 86 int index; /* interface index */ 87 union any_in_addr addr; /* interface address */ 88 char device[LIFNAMSIZ + 1]; /* interface name */ 89 uint64_t flags; /* interface flags */ 90 }; 91 92 #define ERRBUFSIZE 128 /* expected size of third argument */ 93 94 extern int ifaddrlist(struct ifaddrlist **, int, char *); 95 96 /* 97 * Timer queues 98 * 99 * timer queues are a facility for managing timeouts in unix. in the 100 * event driven model, unix provides us with poll(2)/select(3C), which 101 * allow us to coordinate waiting on multiple descriptors with an 102 * optional timeout. however, often (as is the case with the DHCP 103 * agent), we want to manage multiple independent timeouts (say, one 104 * for waiting for an OFFER to come back from a server in response to 105 * a DISCOVER sent out on one interface, and another for waiting for 106 * the T1 time on another interface). timer queues allow us to do 107 * this in the event-driven model. 108 * 109 * note that timer queues do not in and of themselves provide the 110 * event driven model (for instance, there is no handle_events() 111 * routine). they merely provide the hooks to support multiple 112 * independent timeouts. this is done for both simplicity and 113 * applicability (for instance, while one approach would be to use 114 * this timer queue with poll(2), another one would be to use SIGALRM 115 * to wake up periodically, and then process all the expired timers.) 116 */ 117 118 typedef struct iu_timer_queue iu_tq_t; 119 120 /* 121 * a iu_timer_id_t refers to a given timer. its value should not be 122 * interpreted by the interface consumer. it is a signed arithmetic 123 * type, and no valid iu_timer_id_t has the value `-1'. 124 */ 125 126 typedef int iu_timer_id_t; 127 128 #define IU_TIMER_ID_MAX 1024 /* max number of concurrent timers */ 129 130 /* 131 * a iu_tq_callback_t is a function that is called back in response to a 132 * timer expiring. it may then carry out any necessary work, 133 * including rescheduling itself for callback or scheduling / 134 * cancelling other timers. the `void *' argument is the same value 135 * that was passed into iu_schedule_timer(), and if it is dynamically 136 * allocated, it is the callback's responsibility to know that, and to 137 * free it. 138 */ 139 140 typedef void iu_tq_callback_t(iu_tq_t *, void *); 141 142 iu_tq_t *iu_tq_create(void); 143 void iu_tq_destroy(iu_tq_t *); 144 iu_timer_id_t iu_schedule_timer(iu_tq_t *, uint32_t, iu_tq_callback_t *, 145 void *); 146 iu_timer_id_t iu_schedule_timer_ms(iu_tq_t *, uint64_t, iu_tq_callback_t *, 147 void *); 148 int iu_adjust_timer(iu_tq_t *, iu_timer_id_t, uint32_t); 149 int iu_cancel_timer(iu_tq_t *, iu_timer_id_t, void **); 150 int iu_expire_timers(iu_tq_t *); 151 int iu_earliest_timer(iu_tq_t *); 152 153 /* 154 * Event Handler 155 * 156 * an event handler is an object-oriented "wrapper" for select(3C) / 157 * poll(2), aimed to make the event demultiplexing system calls easier 158 * to use and provide a generic reusable component. instead of 159 * applications directly using select(3C) / poll(2), they register 160 * events that should be received with the event handler, providing a 161 * callback function to call when the event occurs. they then call 162 * iu_handle_events() to wait and callback the registered functions 163 * when events occur. also called a `reactor'. 164 */ 165 166 typedef struct iu_event_handler iu_eh_t; 167 168 /* 169 * an iu_event_id_t refers to a given event. its value should not be 170 * interpreted by the interface consumer. it is a signed arithmetic 171 * type, and no valid iu_event_id_t has the value `-1'. 172 */ 173 174 typedef int iu_event_id_t; 175 176 /* 177 * an iu_eh_callback_t is a function that is called back in response to 178 * an event occurring. it may then carry out any work necessary in 179 * response to the event. it receives the file descriptor upon which 180 * the event occurred, a bit array of events that occurred (the same 181 * array used as the revents by poll(2)), and its context through the 182 * `void *' that was originally passed into iu_register_event(). 183 * 184 * NOTE: the same descriptor may not be registered multiple times for 185 * different callbacks. if this behavior is desired, either use dup(2) 186 * to get a unique descriptor, or demultiplex in the callback function 187 * based on the events. 188 */ 189 190 typedef void iu_eh_callback_t(iu_eh_t *, int, short, iu_event_id_t, void *); 191 typedef void iu_eh_sighandler_t(iu_eh_t *, int, void *); 192 typedef boolean_t iu_eh_shutdown_t(iu_eh_t *, void *); 193 194 iu_eh_t *iu_eh_create(void); 195 void iu_eh_destroy(iu_eh_t *); 196 iu_event_id_t iu_register_event(iu_eh_t *, int, short, iu_eh_callback_t *, 197 void *); 198 int iu_unregister_event(iu_eh_t *, iu_event_id_t, void **); 199 int iu_handle_events(iu_eh_t *, iu_tq_t *); 200 void iu_stop_handling_events(iu_eh_t *, unsigned int, 201 iu_eh_shutdown_t *, void *); 202 int iu_eh_register_signal(iu_eh_t *, int, iu_eh_sighandler_t *, 203 void *); 204 int iu_eh_unregister_signal(iu_eh_t *, int, void **); 205 206 #endif /* !defined(_KERNEL) && !defined(_BOOT) */ 207 208 #ifdef __cplusplus 209 } 210 #endif 211 212 #endif /* !_LIBINETUTIL_H */ 213