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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #ifndef _LIBINETUTIL_H 27 #define _LIBINETUTIL_H 28 29 /* 30 * Contains SMI-private API for general Internet functionality 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #include <netinet/inetutil.h> 38 #include <sys/types.h> 39 #include <sys/socket.h> 40 #include <netinet/in.h> 41 #include <net/if.h> 42 43 #if !defined(_KERNEL) && !defined(_BOOT) 44 45 typedef struct { 46 uint_t ifsp_ppa; /* Physical Point of Attachment */ 47 uint_t ifsp_lun; /* Logical Unit number */ 48 boolean_t ifsp_lunvalid; /* TRUE if lun is valid */ 49 char ifsp_devnm[LIFNAMSIZ]; /* only the device name */ 50 } ifspec_t; 51 52 extern boolean_t ifparse_ifspec(const char *, ifspec_t *); 53 extern void get_netmask4(const struct in_addr *, struct in_addr *); 54 extern boolean_t sockaddrcmp(const struct sockaddr_storage *, 55 const struct sockaddr_storage *); 56 extern int plen2mask(uint_t, sa_family_t, struct sockaddr *); 57 extern int mask2plen(const struct sockaddr *); 58 extern boolean_t sockaddrunspec(const struct sockaddr *); 59 60 /* 61 * Extended version of the classic BSD ifaddrlist() interface: 62 * 63 * int ifaddrlist(struct ifaddrlist **addrlistp, int af, uint_t flags, 64 * char *errbuf); 65 * 66 * * addrlistp: Upon success, ifaddrlist() sets *addrlistp to a 67 * dynamically-allocated array of addresses. 68 * 69 * * af: Either AF_INET to obtain IPv4 addresses, or AF_INET6 to 70 * obtain IPv6 addresses. 71 * 72 * * flags: LIFC_* flags that control the classes of interfaces that 73 * will be visible. 74 * 75 * * errbuf: A caller-supplied buffer of ERRBUFSIZE. Upon failure, 76 * provides the reason for the failure. 77 * 78 * Upon success, ifaddrlist() returns the number of addresses in the array 79 * pointed to by `addrlistp'. If the count is 0, then `addrlistp' is NULL. 80 */ 81 union any_in_addr { 82 struct in6_addr addr6; 83 struct in_addr addr; 84 }; 85 86 struct ifaddrlist { 87 int index; /* interface index */ 88 union any_in_addr addr; /* interface address */ 89 char device[LIFNAMSIZ + 1]; /* interface name */ 90 uint64_t flags; /* interface flags */ 91 }; 92 93 #define ERRBUFSIZE 128 /* expected size of fourth argument */ 94 95 extern int ifaddrlist(struct ifaddrlist **, int, uint_t, char *); 96 97 /* 98 * Similar to ifaddrlist(), but returns a linked-list of addresses for a 99 * *specific* interface name, and allows specific address flags to be matched 100 * against. A linked list is used rather than an array so that information 101 * can grow over time without affecting binary compatibility. Also, leaves 102 * error-handling up to the caller. Returns the number of ifaddrlistx's 103 * chained through ifaddrp. 104 * 105 * int ifaddrlistx(const char *ifname, uint64_t set, uint64_t clear, 106 * ifaddrlistx_t **ifaddrp); 107 * 108 * * ifname: Interface name to match against. 109 * 110 * * set: One or more flags that must be set on the address for 111 * it to be returned. 112 * 113 * * clear: Flags that must be clear on the address for it to be 114 * returned. 115 * 116 * * ifaddrp: Upon success, ifaddrlistx() sets *ifaddrp to the head 117 * of a dynamically-allocated array of ifaddrlistx structures. 118 * 119 * Once done, the caller must free `ifaddrp' by calling ifaddrlistx_free(). 120 */ 121 typedef struct ifaddrlistx { 122 struct ifaddrlistx *ia_next; 123 char ia_name[LIFNAMSIZ]; 124 uint64_t ia_flags; 125 struct sockaddr_storage ia_addr; 126 } ifaddrlistx_t; 127 128 extern int ifaddrlistx(const char *, uint64_t, uint64_t, ifaddrlistx_t **); 129 extern void ifaddrlistx_free(ifaddrlistx_t *); 130 131 /* 132 * Timer queues 133 * 134 * timer queues are a facility for managing timeouts in unix. in the 135 * event driven model, unix provides us with poll(2)/select(3C), which 136 * allow us to coordinate waiting on multiple descriptors with an 137 * optional timeout. however, often (as is the case with the DHCP 138 * agent), we want to manage multiple independent timeouts (say, one 139 * for waiting for an OFFER to come back from a server in response to 140 * a DISCOVER sent out on one interface, and another for waiting for 141 * the T1 time on another interface). timer queues allow us to do 142 * this in the event-driven model. 143 * 144 * note that timer queues do not in and of themselves provide the 145 * event driven model (for instance, there is no handle_events() 146 * routine). they merely provide the hooks to support multiple 147 * independent timeouts. this is done for both simplicity and 148 * applicability (for instance, while one approach would be to use 149 * this timer queue with poll(2), another one would be to use SIGALRM 150 * to wake up periodically, and then process all the expired timers.) 151 */ 152 153 typedef struct iu_timer_queue iu_tq_t; 154 155 /* 156 * a iu_timer_id_t refers to a given timer. its value should not be 157 * interpreted by the interface consumer. it is a signed arithmetic 158 * type, and no valid iu_timer_id_t has the value `-1'. 159 */ 160 161 typedef int iu_timer_id_t; 162 163 #define IU_TIMER_ID_MAX 4096 /* max number of concurrent timers */ 164 165 /* 166 * a iu_tq_callback_t is a function that is called back in response to a 167 * timer expiring. it may then carry out any necessary work, 168 * including rescheduling itself for callback or scheduling / 169 * cancelling other timers. the `void *' argument is the same value 170 * that was passed into iu_schedule_timer(), and if it is dynamically 171 * allocated, it is the callback's responsibility to know that, and to 172 * free it. 173 */ 174 175 typedef void iu_tq_callback_t(iu_tq_t *, void *); 176 177 iu_tq_t *iu_tq_create(void); 178 void iu_tq_destroy(iu_tq_t *); 179 iu_timer_id_t iu_schedule_timer(iu_tq_t *, uint32_t, iu_tq_callback_t *, 180 void *); 181 iu_timer_id_t iu_schedule_timer_ms(iu_tq_t *, uint64_t, iu_tq_callback_t *, 182 void *); 183 int iu_adjust_timer(iu_tq_t *, iu_timer_id_t, uint32_t); 184 int iu_cancel_timer(iu_tq_t *, iu_timer_id_t, void **); 185 int iu_expire_timers(iu_tq_t *); 186 int iu_earliest_timer(iu_tq_t *); 187 188 /* 189 * Event Handler 190 * 191 * an event handler is an object-oriented "wrapper" for select(3C) / 192 * poll(2), aimed to make the event demultiplexing system calls easier 193 * to use and provide a generic reusable component. instead of 194 * applications directly using select(3C) / poll(2), they register 195 * events that should be received with the event handler, providing a 196 * callback function to call when the event occurs. they then call 197 * iu_handle_events() to wait and callback the registered functions 198 * when events occur. also called a `reactor'. 199 */ 200 201 typedef struct iu_event_handler iu_eh_t; 202 203 /* 204 * an iu_event_id_t refers to a given event. its value should not be 205 * interpreted by the interface consumer. it is a signed arithmetic 206 * type, and no valid iu_event_id_t has the value `-1'. 207 */ 208 209 typedef int iu_event_id_t; 210 211 /* 212 * an iu_eh_callback_t is a function that is called back in response to 213 * an event occurring. it may then carry out any work necessary in 214 * response to the event. it receives the file descriptor upon which 215 * the event occurred, a bit array of events that occurred (the same 216 * array used as the revents by poll(2)), and its context through the 217 * `void *' that was originally passed into iu_register_event(). 218 * 219 * NOTE: the same descriptor may not be registered multiple times for 220 * different callbacks. if this behavior is desired, either use dup(2) 221 * to get a unique descriptor, or demultiplex in the callback function 222 * based on the events. 223 */ 224 225 typedef void iu_eh_callback_t(iu_eh_t *, int, short, iu_event_id_t, void *); 226 typedef void iu_eh_sighandler_t(iu_eh_t *, int, void *); 227 typedef boolean_t iu_eh_shutdown_t(iu_eh_t *, void *); 228 229 iu_eh_t *iu_eh_create(void); 230 void iu_eh_destroy(iu_eh_t *); 231 iu_event_id_t iu_register_event(iu_eh_t *, int, short, iu_eh_callback_t *, 232 void *); 233 int iu_unregister_event(iu_eh_t *, iu_event_id_t, void **); 234 int iu_handle_events(iu_eh_t *, iu_tq_t *); 235 void iu_stop_handling_events(iu_eh_t *, unsigned int, 236 iu_eh_shutdown_t *, void *); 237 int iu_eh_register_signal(iu_eh_t *, int, iu_eh_sighandler_t *, 238 void *); 239 int iu_eh_unregister_signal(iu_eh_t *, int, void **); 240 241 #endif /* !defined(_KERNEL) && !defined(_BOOT) */ 242 243 #ifdef __cplusplus 244 } 245 #endif 246 247 #endif /* !_LIBINETUTIL_H */ 248