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  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
  24  */
  25 #ifndef _LIBIPADM_H
  26 #define _LIBIPADM_H
  27 
  28 #ifdef  __cplusplus
  29 extern "C" {
  30 #endif
  31 
  32 #include <sys/types.h>
  33 #include <sys/param.h>
  34 #include <sys/socket.h>
  35 #include <net/if.h>
  36 #include <netdb.h>
  37 #include <ifaddrs.h>
  38 #include <libnvpair.h>
  39 #include <netinet/tcp.h>
  40 #include <sys/stropts.h>
  41 
  42 #define IPADM_AOBJ_USTRSIZ      32
  43 #define IPADM_AOBJSIZ           (LIFNAMSIZ + IPADM_AOBJ_USTRSIZ)
  44 #define MAXPROPVALLEN           512
  45 #define LOOPBACK_IF             "lo0"
  46 
  47 /* special timeout values for dhcp operations */
  48 #define IPADM_DHCP_WAIT_DEFAULT (-1)
  49 #define IPADM_DHCP_WAIT_FOREVER (-2)
  50 
  51 /*
  52  * Specifies that the string passed to ipadm_str2nvlist() is a string of comma
  53  * separated names and that each name does not have values associated with it.
  54  */
  55 #define IPADM_NORVAL            0x00000001
  56 
  57 /* error codes */
  58 typedef enum {
  59         IPADM_SUCCESS,          /* No error occurred */
  60         IPADM_FAILURE,          /* Generic failure */
  61         IPADM_EAUTH,            /* Insufficient user authorizations */
  62         IPADM_EPERM,            /* Permission denied */
  63         IPADM_NO_BUFS,          /* No Buffer space available */
  64         IPADM_NO_MEMORY,        /* Insufficient memory */
  65         IPADM_BAD_ADDR,         /* Invalid address */
  66         IPADM_BAD_PROTOCOL,     /* Wrong protocol family for operation */
  67         IPADM_DAD_FOUND,        /* Duplicate address detected */
  68         IPADM_EXISTS,           /* Already exists */
  69         IPADM_IF_EXISTS,        /* Interface already exists */
  70         IPADM_ADDROBJ_EXISTS,   /* Address object already exists */
  71         IPADM_ADDRCONF_EXISTS,  /* Addrconf already in progress */
  72         IPADM_ENXIO,            /* Interface does not exist */
  73         IPADM_GRP_NOTEMPTY,     /* IPMP Group non-empty on unplumb */
  74         IPADM_INVALID_ARG,      /* Invalid argument */
  75         IPADM_INVALID_NAME,     /* Invalid name */
  76         IPADM_DLPI_FAILURE,     /* Could not open DLPI link */
  77         IPADM_DLADM_FAILURE,    /* DLADM error encountered */
  78         IPADM_PROP_UNKNOWN,     /* Unknown property */
  79         IPADM_ERANGE,           /* Value is outside the allowed range */
  80         IPADM_ESRCH,            /* Value does not exist */
  81         IPADM_EOVERFLOW,        /* Number of values exceed the allowed limit */
  82         IPADM_NOTFOUND,         /* Object not found */
  83         IPADM_IF_INUSE,         /* Interface already in use */
  84         IPADM_ADDR_INUSE,       /* Address alrelady in use */
  85         IPADM_BAD_HOSTNAME,     /* hostname maps to multiple IP addresses */
  86         IPADM_ADDR_NOTAVAIL,    /* Can't assign requested address */
  87         IPADM_ALL_ADDRS_NOT_ENABLED, /* All addresses could not be enabled */
  88         IPADM_NDPD_NOT_RUNNING, /* in.ndpd not running */
  89         IPADM_DHCP_START_ERROR, /* Cannot start dhcpagent */
  90         IPADM_DHCP_IPC_ERROR,   /* Cannot communicate with dhcpagent */
  91         IPADM_DHCP_IPC_TIMEOUT, /* Communication with dhcpagent timed out */
  92         IPADM_TEMPORARY_OBJ,    /* Permanent operation on temporary object */
  93         IPADM_IPC_ERROR,        /* Cannot communicate with ipmgmtd */
  94         IPADM_OP_DISABLE_OBJ,   /* Operation on disable object */
  95         IPADM_NOTSUP,           /* Operation not supported */
  96         IPADM_EBADE,            /* Invalid data exchange with ipmgmtd */
  97         IPADM_GZ_PERM           /* Operation not permitted on from-gz intf */
  98 } ipadm_status_t;
  99 
 100 /*
 101  * option flags taken by the libipadm functions
 102  *
 103  *  - IPADM_OPT_PERSIST:
 104  *      For all the create/delete/up/down/set/get functions,
 105  *      requests to persist the configuration so that it can be
 106  *      re-enabled or re-applied on boot.
 107  *
 108  *  - IPADM_OPT_ACTIVE:
 109  *      Requests to apply configuration without persisting it and
 110  *      used by show-* subcommands to retrieve current values.
 111  *
 112  *  - IPADM_OPT_DEFAULT:
 113  *      retrieves the default value for a given property
 114  *
 115  *  - IPADM_OPT_PERM
 116  *      retrieves the permission for a given property
 117  *
 118  *  - IPADM_OPT_POSSIBLE
 119  *      retrieves the range of values for a given property
 120  *
 121  *  - IPADM_OPT_APPEND
 122  *      for multi-valued properties, appends a new value.
 123  *
 124  *  - IPADM_OPT_REMOVE
 125  *      for multi-valued properties, removes the specified value
 126  *
 127  *  - IPADM_OPT_IPMP
 128  *      Used in ipadm_create_if() to plumb ipmp interfaces.
 129  *
 130  *  - IPADM_OPT_GENPPA
 131  *      Used in ipadm_create_if() to generate a ppa for the given interface.
 132  *
 133  *  - IPADM_OPT_ZEROADDR
 134  *      return :: or INADDR_ANY
 135  *
 136  *  - IPADM_OPT_RELEASE
 137  *      Used to release the lease on a dhcp address object
 138  *
 139  *  - IPADM_OPT_INFORM
 140  *      Used to perform DHCP_INFORM on a specified static address object
 141  *
 142  *  - IPADM_OPT_UP
 143  *      Used to bring up a static address on creation
 144  *
 145  *  - IPADM_OPT_V46
 146  *      Used to plumb both IPv4 and IPv6 interfaces by ipadm_create_addr()
 147  *
 148  *  - IPADM_OPT_SET_PROPS
 149  *      Used to indicate the update changes the running configuration of
 150  *      "props" data on the object. The props are cached there on the parent,
 151  *      but the PROPS_ONLY change does not affect the ACTIVE/PERSIST state of
 152  *      the parent.
 153  *
 154  *  - IPADM_OPT_PERSIST_PROPS
 155  *      Used when IPADM_OPT_SET_PROPS is active to indicate the update changes
 156  *  the persistent configuration of the "props" data on the object.
 157  */
 158 #define IPADM_OPT_PERSIST       0x00000001
 159 #define IPADM_OPT_ACTIVE        0x00000002
 160 #define IPADM_OPT_DEFAULT       0x00000004
 161 #define IPADM_OPT_PERM          0x00000008
 162 #define IPADM_OPT_POSSIBLE      0x00000010
 163 #define IPADM_OPT_APPEND        0x00000020
 164 #define IPADM_OPT_REMOVE        0x00000040
 165 #define IPADM_OPT_IPMP          0x00000080
 166 #define IPADM_OPT_GENPPA        0x00000100
 167 #define IPADM_OPT_ZEROADDR      0x00000200
 168 #define IPADM_OPT_RELEASE       0x00000400
 169 #define IPADM_OPT_INFORM        0x00000800
 170 #define IPADM_OPT_UP            0x00001000
 171 #define IPADM_OPT_V46           0x00002000
 172 #define IPADM_OPT_SET_PROPS     0x00004000
 173 #define IPADM_OPT_PERSIST_PROPS         0x00008000
 174 
 175 /* IPADM property class */
 176 #define IPADMPROP_CLASS_MODULE  0x00000001      /* on 'protocol' only */
 177 #define IPADMPROP_CLASS_IF      0x00000002      /* on 'IP interface' only */
 178 #define IPADMPROP_CLASS_ADDR    0x00000004      /* on 'IP address' only */
 179 /* protocol property that can be applied on interface too */
 180 #define IPADMPROP_CLASS_MODIF   (IPADMPROP_CLASS_MODULE | IPADMPROP_CLASS_IF)
 181 
 182 /* opaque ipadm handle to libipadm functions */
 183 struct ipadm_handle;
 184 typedef struct ipadm_handle     *ipadm_handle_t;
 185 
 186 /* ipadm_handle flags */
 187 #define IPH_VRRP                0x00000001      /* Caller is VRRP */
 188 #define IPH_LEGACY              0x00000002      /* Caller is legacy app */
 189 #define IPH_IPMGMTD             0x00000004      /* Caller is ipmgmtd itself */
 190 /*
 191  * Indicates that the operation being invoked is in 'init' context. This is
 192  * a library private flag.
 193  */
 194 #define IPH_INIT                0x10000000
 195 
 196 /* opaque address object structure */
 197 typedef struct ipadm_addrobj_s  *ipadm_addrobj_t;
 198 
 199 /* ipadm_if_info_t states */
 200 typedef enum {
 201         IFIS_OK,                /* Interface is usable */
 202         IFIS_DOWN,              /* Interface has no UP addresses */
 203         IFIS_FAILED,            /* Interface has failed. */
 204         IFIS_OFFLINE,           /* Interface has been offlined */
 205         IFIS_DISABLED           /* Interface has been disabled. */
 206 } ipadm_if_state_t;
 207 
 208 typedef struct ipadm_if_info_s {
 209         struct ipadm_if_info_s  *ifi_next;
 210         char                    ifi_name[LIFNAMSIZ];    /* interface name */
 211         ipadm_if_state_t        ifi_state;              /* see above */
 212         uint_t                  ifi_cflags;             /* current flags */
 213         uint_t                  ifi_pflags;             /* persistent flags */
 214 } ipadm_if_info_t;
 215 
 216 /* ipadm_if_info_t flags */
 217 #define IFIF_BROADCAST          0x00000001
 218 #define IFIF_MULTICAST          0x00000002
 219 #define IFIF_POINTOPOINT        0x00000004
 220 #define IFIF_VIRTUAL            0x00000008
 221 #define IFIF_IPMP               0x00000010
 222 #define IFIF_STANDBY            0x00000020
 223 #define IFIF_INACTIVE           0x00000040
 224 #define IFIF_VRRP               0x00000080
 225 #define IFIF_NOACCEPT           0x00000100
 226 #define IFIF_IPV4               0x00000200
 227 #define IFIF_IPV6               0x00000400
 228 #define IFIF_L3PROTECT          0x00000800
 229 
 230 /* ipadm_addr_info_t state */
 231 typedef enum {
 232         IFA_DISABLED,           /* Address not in active configuration. */
 233         IFA_DUPLICATE,          /* DAD failed. */
 234         IFA_DOWN,               /* Address is not IFF_UP */
 235         IFA_TENTATIVE,          /* DAD verification initiated */
 236         IFA_OK,                 /* Address is usable */
 237         IFA_INACCESSIBLE        /* Interface has failed */
 238 } ipadm_addr_state_t;
 239 
 240 /* possible address types */
 241 typedef enum  {
 242         IPADM_ADDR_NONE,
 243         IPADM_ADDR_STATIC,
 244         IPADM_ADDR_IPV6_ADDRCONF,
 245         IPADM_ADDR_DHCP
 246 } ipadm_addr_type_t;
 247 
 248 typedef struct ipadm_addr_info_s {
 249         struct ifaddrs          ia_ifa;         /* list of addresses */
 250         char                    ia_sname[NI_MAXHOST];   /* local hostname */
 251         char                    ia_dname[NI_MAXHOST];   /* remote hostname */
 252         char                    ia_aobjname[IPADM_AOBJSIZ];
 253         uint_t                  ia_cflags;      /* active flags */
 254         uint_t                  ia_pflags;      /* persistent flags */
 255         ipadm_addr_type_t       ia_atype;       /* see above */
 256         ipadm_addr_state_t      ia_state;       /* see above */
 257 } ipadm_addr_info_t;
 258 #define IA_NEXT(ia)             ((ipadm_addr_info_t *)(ia->ia_ifa.ifa_next))
 259 
 260 /* ipadm_addr_info_t flags */
 261 #define IA_UP                   0x00000001
 262 #define IA_UNNUMBERED           0x00000002
 263 #define IA_PRIVATE              0x00000004
 264 #define IA_TEMPORARY            0x00000008
 265 #define IA_DEPRECATED           0x00000010
 266 
 267 /* open/close libipadm handle */
 268 extern ipadm_status_t   ipadm_open(ipadm_handle_t *, uint32_t);
 269 extern void             ipadm_close(ipadm_handle_t);
 270 
 271 /* Check authorization for network configuration */
 272 extern boolean_t        ipadm_check_auth(void);
 273 /*
 274  * Interface management functions
 275  */
 276 extern ipadm_status_t   ipadm_create_if(ipadm_handle_t, char *, sa_family_t,
 277                             uint32_t);
 278 extern ipadm_status_t   ipadm_disable_if(ipadm_handle_t, const char *,
 279                             uint32_t);
 280 extern ipadm_status_t   ipadm_enable_if(ipadm_handle_t, const char *, uint32_t);
 281 extern ipadm_status_t   ipadm_if_info(ipadm_handle_t, const char *,
 282                             ipadm_if_info_t **, uint32_t, int64_t);
 283 extern void             ipadm_free_if_info(ipadm_if_info_t *);
 284 extern ipadm_status_t   ipadm_delete_if(ipadm_handle_t, const char *,
 285                             sa_family_t, uint32_t);
 286 extern void             ipadm_if_move(ipadm_handle_t, const char *);
 287 
 288 /*
 289  * Address management functions
 290  */
 291 extern ipadm_status_t   ipadm_create_addr(ipadm_handle_t, ipadm_addrobj_t,
 292                             uint32_t);
 293 extern ipadm_status_t   ipadm_disable_addr(ipadm_handle_t, const char *,
 294                             uint32_t);
 295 extern ipadm_status_t   ipadm_enable_addr(ipadm_handle_t, const char *,
 296                             uint32_t);
 297 extern ipadm_status_t   ipadm_addr_info(ipadm_handle_t, const char *,
 298                             ipadm_addr_info_t **, uint32_t, int64_t);
 299 extern void             ipadm_free_addr_info(ipadm_addr_info_t *);
 300 extern ipadm_status_t   ipadm_up_addr(ipadm_handle_t, const char *,
 301                             uint32_t);
 302 extern ipadm_status_t   ipadm_down_addr(ipadm_handle_t, const char *,
 303                             uint32_t);
 304 extern ipadm_status_t   ipadm_refresh_addr(ipadm_handle_t, const char *,
 305                             uint32_t);
 306 extern ipadm_status_t   ipadm_delete_addr(ipadm_handle_t, const char *,
 307                             uint32_t);
 308 
 309 /* Functions related to creating/deleting/modifying opaque address object */
 310 extern ipadm_status_t   ipadm_create_addrobj(ipadm_addr_type_t, const char *,
 311                             ipadm_addrobj_t *);
 312 extern void             ipadm_destroy_addrobj(ipadm_addrobj_t);
 313 extern ipadm_status_t   ipadm_get_aobjname(const ipadm_addrobj_t, char *,
 314                             size_t);
 315 
 316 /* Functions to set fields in addrobj for static addresses */
 317 extern ipadm_status_t   ipadm_set_addr(ipadm_addrobj_t, const char *,
 318                             sa_family_t);
 319 extern ipadm_status_t   ipadm_set_dst_addr(ipadm_addrobj_t, const char *,
 320                             sa_family_t);
 321 extern ipadm_status_t   ipadm_get_addr(const ipadm_addrobj_t,
 322                             struct sockaddr_storage *);
 323 
 324 /* Functions to set fields in addrobj for IPv6 addrconf */
 325 extern ipadm_status_t   ipadm_set_interface_id(ipadm_addrobj_t, const char *);
 326 extern ipadm_status_t   ipadm_set_stateless(ipadm_addrobj_t, boolean_t);
 327 extern ipadm_status_t   ipadm_set_stateful(ipadm_addrobj_t, boolean_t);
 328 
 329 /* Functions to set fields in addrobj for DHCP */
 330 extern ipadm_status_t   ipadm_set_primary(ipadm_addrobj_t, boolean_t);
 331 extern ipadm_status_t   ipadm_set_wait_time(ipadm_addrobj_t, int32_t);
 332 extern ipadm_status_t   ipadm_set_reqhost(ipadm_addrobj_t, const char *);
 333 
 334 /*
 335  * Property management functions
 336  */
 337 /* call back function for the property walker */
 338 typedef boolean_t       ipadm_prop_wfunc_t(void *, const char *, uint_t);
 339 extern ipadm_status_t   ipadm_walk_proptbl(uint_t, uint_t, ipadm_prop_wfunc_t *,
 340                             void *);
 341 extern ipadm_status_t   ipadm_walk_prop(const char *, uint_t, uint_t,
 342                             ipadm_prop_wfunc_t *, void *);
 343 
 344 /* Interface property management - set, reset and get */
 345 extern ipadm_status_t   ipadm_set_ifprop(ipadm_handle_t, const char *,
 346                             const char *, const char *, uint_t, uint_t);
 347 extern ipadm_status_t   ipadm_get_ifprop(ipadm_handle_t, const char *,
 348                             const char *, char *, uint_t *, uint_t, uint_t);
 349 
 350 /* Address property management - set, reset and get */
 351 extern ipadm_status_t   ipadm_set_addrprop(ipadm_handle_t, const char *,
 352                             const char *, const char *, uint_t);
 353 extern ipadm_status_t   ipadm_get_addrprop(ipadm_handle_t, const char *, char *,
 354                             uint_t *, const char *, uint_t);
 355 
 356 /* Protoocl property management - set, reset and get */
 357 extern ipadm_status_t   ipadm_set_prop(ipadm_handle_t, const char *,
 358                             const char *, uint_t, uint_t);
 359 extern ipadm_status_t   ipadm_get_prop(ipadm_handle_t, const char *, char *,
 360                             uint_t *, uint_t, uint_t);
 361 
 362 /*
 363  * miscellaneous helper functions.
 364  */
 365 extern const char       *ipadm_status2str(ipadm_status_t);
 366 extern int              ipadm_str2nvlist(const char *, nvlist_t **, uint_t);
 367 extern size_t           ipadm_nvlist2str(nvlist_t *, char *, size_t);
 368 extern char             *ipadm_proto2str(uint_t);
 369 extern uint_t           ipadm_str2proto(const char *);
 370 extern ipadm_status_t   ipadm_open_arp_on_udp(const char *, int *);
 371 extern int              ipadm_legacy2new_propname(const char *, char *,
 372                             uint_t, uint_t *);
 373 extern int              ipadm_new2legacy_propname(const char *, char *,
 374                             uint_t, uint_t);
 375 extern boolean_t        ipadm_is_valid_hostname(const char *hostname);
 376 extern boolean_t        ipadm_is_nil_hostname(const char *hostname);
 377 
 378 #ifdef  __cplusplus
 379 }
 380 #endif
 381 
 382 #endif  /* _LIBIPADM_H */