1 /* 2 * Copyright (c) 2016-2017, Marie Helene Kvello-Aune 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * thislist of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation and/or 13 * other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #pragma once 28 29 #include <sys/types.h> 30 31 #include <net/if.h> 32 #include <net/if_bridgevar.h> /* for ifbvlan_set_t */ 33 34 #include <netinet/in.h> 35 #include <netinet/ip_carp.h> 36 #include <netinet6/in6_var.h> 37 38 #include <stdbool.h> 39 40 #define ND6_IFF_DEFAULTIF 0x8000 41 42 typedef enum { 43 OK = 0, 44 OTHER, 45 IOCTL, 46 SOCKET, 47 NETLINK 48 } ifconfig_errtype; 49 50 /* 51 * Opaque definition so calling application can just pass a 52 * pointer to it for library use. 53 */ 54 struct ifconfig_handle; 55 typedef struct ifconfig_handle ifconfig_handle_t; 56 57 struct ifaddrs; 58 struct ifbropreq; 59 struct ifbreq; 60 struct in6_ndireq; 61 struct lagg_reqall; 62 struct lagg_reqflags; 63 struct lagg_reqopts; 64 struct lagg_reqport; 65 66 /** Stores extra info associated with a bridge(4) interface */ 67 struct ifconfig_bridge_status { 68 struct ifbropreq *params; /**< current operational parameters */ 69 struct ifbreq *members; /**< list of bridge members */ 70 ifbvlan_set_t *member_vlans; /**< bridge member vlan sets */ 71 size_t members_count; /**< how many member interfaces */ 72 uint32_t cache_size; /**< size of address cache */ 73 uint32_t cache_lifetime; /**< address cache entry lifetime */ 74 ifbr_flags_t flags; /**< bridge flags */ 75 ether_vlanid_t defpvid; /**< default pvid */ 76 }; 77 78 struct ifconfig_capabilities { 79 /** Current capabilities (ifconfig prints this as 'options')*/ 80 int curcap; 81 /** Requested capabilities (ifconfig prints this as 'capabilities')*/ 82 int reqcap; 83 }; 84 85 /** Stores extra info associated with an inet address */ 86 struct ifconfig_inet_addr { 87 const struct sockaddr_in *sin; 88 const struct sockaddr_in *netmask; 89 const struct sockaddr_in *dst; 90 const struct sockaddr_in *broadcast; 91 int prefixlen; 92 uint8_t vhid; 93 }; 94 95 /** Stores extra info associated with an inet6 address */ 96 struct ifconfig_inet6_addr { 97 struct sockaddr_in6 *sin6; 98 struct sockaddr_in6 *dstin6; 99 struct in6_addrlifetime lifetime; 100 int prefixlen; 101 uint32_t flags; 102 uint8_t vhid; 103 }; 104 105 /** Stores extra info associated with a lagg(4) interface */ 106 struct ifconfig_lagg_status { 107 struct lagg_reqall *ra; 108 struct lagg_reqopts *ro; 109 struct lagg_reqflags *rf; 110 }; 111 112 /** Retrieves a new state object for use in other API calls. 113 * Example usage: 114 *{@code 115 * // Create state object 116 * ifconfig_handle_t *lifh; 117 * lifh = ifconfig_open(); 118 * if (lifh == NULL) { 119 * // Handle error 120 * } 121 * 122 * // Do stuff with the handle 123 * 124 * // Dispose of the state object 125 * ifconfig_close(lifh); 126 * lifh = NULL; 127 *} 128 */ 129 ifconfig_handle_t *ifconfig_open(void); 130 131 /** Frees resources held in the provided state object. 132 * @param h The state object to close. 133 * @see #ifconfig_open(void) 134 */ 135 void ifconfig_close(ifconfig_handle_t *h); 136 137 /** Identifies what kind of error occurred. */ 138 ifconfig_errtype ifconfig_err_errtype(ifconfig_handle_t *h); 139 140 /** Retrieves the errno associated with the error, if any. */ 141 int ifconfig_err_errno(ifconfig_handle_t *h); 142 143 typedef void (*ifconfig_foreach_func_t)(ifconfig_handle_t *h, 144 struct ifaddrs *ifa, void *udata); 145 146 /** Iterate over every network interface 147 * @param h An open ifconfig state object 148 * @param cb A callback function to call with a pointer to each interface 149 * @param udata An opaque value that will be passed to the callback. 150 * @return 0 on success, nonzero if the list could not be iterated 151 */ 152 int ifconfig_foreach_iface(ifconfig_handle_t *h, ifconfig_foreach_func_t cb, 153 void *udata); 154 155 /** Iterate over every address on a single network interface 156 * @param h An open ifconfig state object 157 * @param ifa A pointer that was supplied by a previous call to 158 * ifconfig_foreach_iface 159 * @param udata An opaque value that will be passed to the callback. 160 * @param cb A callback function to call with a pointer to each ifaddr 161 */ 162 void ifconfig_foreach_ifaddr(ifconfig_handle_t *h, struct ifaddrs *ifa, 163 ifconfig_foreach_func_t cb, void *udata); 164 165 /** If error type was IOCTL, this identifies which request failed. */ 166 unsigned long ifconfig_err_ioctlreq(ifconfig_handle_t *h); 167 int ifconfig_get_description(ifconfig_handle_t *h, const char *name, 168 char **description); 169 int ifconfig_set_description(ifconfig_handle_t *h, const char *name, 170 const char *newdescription); 171 int ifconfig_unset_description(ifconfig_handle_t *h, const char *name); 172 int ifconfig_set_name(ifconfig_handle_t *h, const char *name, 173 const char *newname); 174 int ifconfig_get_orig_name(ifconfig_handle_t *h, const char *ifname, 175 char **orig_name); 176 int ifconfig_get_fib(ifconfig_handle_t *h, const char *name, int *fib); 177 int ifconfig_set_mtu(ifconfig_handle_t *h, const char *name, const int mtu); 178 int ifconfig_get_mtu(ifconfig_handle_t *h, const char *name, int *mtu); 179 int ifconfig_get_nd6(ifconfig_handle_t *h, const char *name, 180 struct in6_ndireq *nd); 181 int ifconfig_set_metric(ifconfig_handle_t *h, const char *name, 182 const int metric); 183 int ifconfig_get_metric(ifconfig_handle_t *h, const char *name, int *metric); 184 int ifconfig_set_capability(ifconfig_handle_t *h, const char *name, 185 const int capability); 186 int ifconfig_get_capability(ifconfig_handle_t *h, const char *name, 187 struct ifconfig_capabilities *capability); 188 189 /** Retrieve the list of groups to which this interface belongs 190 * @param h An open ifconfig state object 191 * @param name The interface name 192 * @param ifgr return argument. The caller is responsible for freeing 193 * ifgr->ifgr_groups 194 * @return 0 on success, nonzero on failure 195 */ 196 int ifconfig_get_groups(ifconfig_handle_t *h, const char *name, 197 struct ifgroupreq *ifgr); 198 int ifconfig_get_ifstatus(ifconfig_handle_t *h, const char *name, 199 struct ifstat *stat); 200 201 /** Retrieve the interface media information 202 * @param h An open ifconfig state object 203 * @param name The interface name 204 * @param ifmr Return argument. The caller is responsible for freeing it 205 * @return 0 on success, nonzero on failure 206 */ 207 int ifconfig_media_get_mediareq(ifconfig_handle_t *h, const char *name, 208 struct ifmediareq **ifmr); 209 210 const char *ifconfig_media_get_status(const struct ifmediareq *ifmr); 211 212 typedef int ifmedia_t; 213 214 #define INVALID_IFMEDIA ((ifmedia_t)-1) 215 216 /** Retrieve the name of a media type 217 * @param media The media to be named 218 * @return A pointer to the media type name, or NULL on failure 219 */ 220 const char *ifconfig_media_get_type(ifmedia_t media); 221 222 /** Retrieve a media type by its name 223 * @param name The name of a media type 224 * @return The media type value, or INVALID_IFMEDIA on failure 225 */ 226 ifmedia_t ifconfig_media_lookup_type(const char *name); 227 228 /** Retrieve the name of a media subtype 229 * @param media The media subtype to be named 230 * @return A pointer to the media subtype name, or NULL on failure 231 */ 232 const char *ifconfig_media_get_subtype(ifmedia_t media); 233 234 /** Retrieve a media subtype by its name 235 * @param media The top level media type whose subtype we want 236 * @param name The name of a media subtype 237 * @return The media subtype value, or INVALID_IFMEDIA on failure 238 */ 239 ifmedia_t ifconfig_media_lookup_subtype(ifmedia_t media, const char *name); 240 241 /** Retrieve the name of a media mode 242 * @param media The media mode to be named 243 * @return A pointer to the media mode name, or NULL on failure 244 */ 245 const char *ifconfig_media_get_mode(ifmedia_t media); 246 247 /** Retrieve a media mode by its name 248 * @param media The top level media type whose mode we want 249 * @param name The name of a media mode 250 * @return The media mode value, or INVALID_IFMEDIA on failure 251 */ 252 ifmedia_t ifconfig_media_lookup_mode(ifmedia_t media, const char *name); 253 254 /** Retrieve an array of media options 255 * @param media The media for which to obtain the options 256 * @return Pointer to an array of pointers to option names, 257 * terminated by a NULL pointer, or simply NULL on failure. 258 * The caller is responsible for freeing the array but not its 259 * contents. 260 */ 261 const char **ifconfig_media_get_options(ifmedia_t media); 262 263 /** Retrieve an array of media options by names 264 * @param media The top level media type whose options we want 265 * @param opts Pointer to an array of string pointers naming options 266 * @param nopts Number of elements in the opts array 267 * @return Pointer to an array of media options, one for each option named 268 * in opts. NULL is returned instead with errno set to ENOMEM if 269 * allocating the return array fails or EINVAL if media is not 270 * valid. A media option in the array will be INVALID_IFMEDIA 271 * when lookup failed for the option named in that position in 272 * opts. The caller is responsible for freeing the array. 273 */ 274 ifmedia_t *ifconfig_media_lookup_options(ifmedia_t media, const char **opts, 275 size_t nopts); 276 277 /** Retrieve the reason the interface is down 278 * @param h An open ifconfig state object 279 * @param name The interface name 280 * @param ifdr Return argument. 281 * @return 0 on success, nonzero on failure 282 */ 283 int ifconfig_media_get_downreason(ifconfig_handle_t *h, const char *name, 284 struct ifdownreason *ifdr); 285 286 struct ifconfig_carp { 287 size_t carpr_count; 288 uint32_t carpr_vhid; 289 uint32_t carpr_state; 290 int32_t carpr_advbase; 291 int32_t carpr_advskew; 292 uint8_t carpr_key[CARP_KEY_LEN]; 293 struct in_addr carpr_addr; 294 struct in6_addr carpr_addr6; 295 carp_version_t carpr_version; 296 uint8_t carpr_vrrp_prio; 297 uint16_t carpr_vrrp_adv_inter; 298 }; 299 300 int ifconfig_carp_get_vhid(ifconfig_handle_t *h, const char *name, 301 struct ifconfig_carp *carpr, uint32_t vhid); 302 int ifconfig_carp_get_info(ifconfig_handle_t *h, const char *name, 303 struct ifconfig_carp *carpr, size_t ncarp); 304 int ifconfig_carp_set_info(ifconfig_handle_t *h, const char *name, 305 const struct ifconfig_carp *carpr); 306 307 /** Retrieve additional information about an inet address 308 * @param h An open ifconfig state object 309 * @param name The interface name 310 * @param ifa Pointer to the address structure of interest 311 * @param addr Return argument. It will be filled with additional information 312 * about the address. 313 * @return 0 on success, nonzero on failure. 314 */ 315 int ifconfig_inet_get_addrinfo(ifconfig_handle_t *h, 316 const char *name, struct ifaddrs *ifa, struct ifconfig_inet_addr *addr); 317 318 /** Retrieve additional information about an inet6 address 319 * @param h An open ifconfig state object 320 * @param name The interface name 321 * @param ifa Pointer to the address structure of interest 322 * @param addr Return argument. It will be filled with additional information 323 * about the address. 324 * @return 0 on success, nonzero on failure. 325 */ 326 int ifconfig_inet6_get_addrinfo(ifconfig_handle_t *h, 327 const char *name, struct ifaddrs *ifa, struct ifconfig_inet6_addr *addr); 328 329 /** Retrieve additional information about a bridge(4) interface */ 330 int ifconfig_bridge_get_bridge_status(ifconfig_handle_t *h, 331 const char *name, struct ifconfig_bridge_status **bridge); 332 333 /** Frees the structure returned by ifconfig_bridge_get_bridge_status. Does 334 * nothing if the argument is NULL 335 * @param bridge Pointer to the structure to free 336 */ 337 void ifconfig_bridge_free_bridge_status(struct ifconfig_bridge_status *bridge); 338 339 /** Retrieve additional information about a lagg(4) interface */ 340 int ifconfig_lagg_get_lagg_status(ifconfig_handle_t *h, 341 const char *name, struct ifconfig_lagg_status **lagg_status); 342 343 /** Retrieve additional information about a member of a lagg(4) interface */ 344 int ifconfig_lagg_get_laggport_status(ifconfig_handle_t *h, 345 const char *name, struct lagg_reqport *rp); 346 347 /** Frees the structure returned by ifconfig_lagg_get_lagg_status. Does 348 * nothing if the argument is NULL 349 * @param laggstat Pointer to the structure to free 350 */ 351 void ifconfig_lagg_free_lagg_status(struct ifconfig_lagg_status *laggstat); 352 353 /** Destroy a virtual interface 354 * @param name Interface to destroy 355 */ 356 int ifconfig_destroy_interface(ifconfig_handle_t *h, const char *name); 357 358 /** Creates a (virtual) interface 359 * @param name Name of interface to create. Example: bridge or bridge42 360 * @param name ifname Is set to actual name of created interface 361 */ 362 int ifconfig_create_interface(ifconfig_handle_t *h, const char *name, 363 char **ifname); 364 365 /** Creates a (virtual) interface 366 * @param name Name of interface to create. Example: vlan0 or ix0.50 367 * @param name ifname Is set to actual name of created interface 368 * @param vlandev Name of interface to attach to 369 * @param vlanid VLAN ID/Tag. Must not be 0. 370 */ 371 int ifconfig_create_interface_vlan(ifconfig_handle_t *h, const char *name, 372 char **ifname, const char *vlandev, const unsigned short vlantag); 373 374 int ifconfig_set_vlantag(ifconfig_handle_t *h, const char *name, 375 const char *vlandev, const unsigned short vlantag); 376 377 /** Gets the names of all interface cloners available on the system 378 * @param bufp Set to the address of the names buffer on success or NULL 379 * if an error occurs. This buffer must be freed when done. 380 * @param lenp Set to the number of names in the returned buffer or 0 381 * if an error occurs. Each name is contained within an 382 * IFNAMSIZ length slice of the buffer, for a total buffer 383 * length of *lenp * IFNAMSIZ bytes. 384 */ 385 int ifconfig_list_cloners(ifconfig_handle_t *h, char **bufp, size_t *lenp); 386 387 /** Brings the interface up/down 388 * @param h An open ifconfig state object 389 * @param ifname The interface name 390 * @param up true to bring the interface up, false to bring it down 391 * @return 0 on success, nonzero on failure. 392 * On failure, the error info on the handle is set. 393 */ 394 int ifconfig_set_up(ifconfig_handle_t *h, const char *ifname, bool up); 395