16e91bba0SGirish Moodalbail /* 26e91bba0SGirish Moodalbail * CDDL HEADER START 36e91bba0SGirish Moodalbail * 46e91bba0SGirish Moodalbail * The contents of this file are subject to the terms of the 56e91bba0SGirish Moodalbail * Common Development and Distribution License (the "License"). 66e91bba0SGirish Moodalbail * You may not use this file except in compliance with the License. 76e91bba0SGirish Moodalbail * 86e91bba0SGirish Moodalbail * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96e91bba0SGirish Moodalbail * or http://www.opensolaris.org/os/licensing. 106e91bba0SGirish Moodalbail * See the License for the specific language governing permissions 116e91bba0SGirish Moodalbail * and limitations under the License. 126e91bba0SGirish Moodalbail * 136e91bba0SGirish Moodalbail * When distributing Covered Code, include this CDDL HEADER in each 146e91bba0SGirish Moodalbail * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156e91bba0SGirish Moodalbail * If applicable, add the following below this CDDL HEADER, with the 166e91bba0SGirish Moodalbail * fields enclosed by brackets "[]" replaced with your own identifying 176e91bba0SGirish Moodalbail * information: Portions Copyright [yyyy] [name of copyright owner] 186e91bba0SGirish Moodalbail * 196e91bba0SGirish Moodalbail * CDDL HEADER END 206e91bba0SGirish Moodalbail */ 216e91bba0SGirish Moodalbail /* 228b88711aSGirish Moodalbail * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23*7bc87895SYuri Pankov * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 246e91bba0SGirish Moodalbail */ 256e91bba0SGirish Moodalbail #include <arpa/inet.h> 266e91bba0SGirish Moodalbail #include <errno.h> 276e91bba0SGirish Moodalbail #include <getopt.h> 286e91bba0SGirish Moodalbail #include <inet/ip.h> 296e91bba0SGirish Moodalbail #include <inet/iptun.h> 306e91bba0SGirish Moodalbail #include <inet/tunables.h> 316e91bba0SGirish Moodalbail #include <libdladm.h> 326e91bba0SGirish Moodalbail #include <libdliptun.h> 336e91bba0SGirish Moodalbail #include <libdllink.h> 346e91bba0SGirish Moodalbail #include <libinetutil.h> 356e91bba0SGirish Moodalbail #include <libipadm.h> 366e91bba0SGirish Moodalbail #include <locale.h> 376e91bba0SGirish Moodalbail #include <netdb.h> 386e91bba0SGirish Moodalbail #include <netinet/in.h> 396e91bba0SGirish Moodalbail #include <ofmt.h> 406e91bba0SGirish Moodalbail #include <stdarg.h> 416e91bba0SGirish Moodalbail #include <stddef.h> 426e91bba0SGirish Moodalbail #include <stdio.h> 436e91bba0SGirish Moodalbail #include <stdlib.h> 446e91bba0SGirish Moodalbail #include <string.h> 456e91bba0SGirish Moodalbail #include <strings.h> 466e91bba0SGirish Moodalbail #include <sys/stat.h> 476e91bba0SGirish Moodalbail #include <sys/types.h> 486e91bba0SGirish Moodalbail #include <zone.h> 496e91bba0SGirish Moodalbail 506e91bba0SGirish Moodalbail #define STR_UNKNOWN_VAL "?" 516e91bba0SGirish Moodalbail #define LIFC_DEFAULT (LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES |\ 526e91bba0SGirish Moodalbail LIFC_UNDER_IPMP) 536e91bba0SGirish Moodalbail 546e91bba0SGirish Moodalbail typedef void cmdfunc_t(int, char **, const char *); 556e91bba0SGirish Moodalbail static cmdfunc_t do_create_if, do_delete_if, do_enable_if, do_disable_if; 566e91bba0SGirish Moodalbail static cmdfunc_t do_show_if; 578887b57dSGirish Moodalbail static cmdfunc_t do_set_prop, do_show_prop, do_set_ifprop; 586e91bba0SGirish Moodalbail static cmdfunc_t do_show_ifprop, do_reset_ifprop, do_reset_prop; 596e91bba0SGirish Moodalbail static cmdfunc_t do_show_addrprop, do_set_addrprop, do_reset_addrprop; 606e91bba0SGirish Moodalbail static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr; 616e91bba0SGirish Moodalbail static cmdfunc_t do_enable_addr, do_disable_addr; 626e91bba0SGirish Moodalbail static cmdfunc_t do_up_addr, do_down_addr, do_refresh_addr; 636e91bba0SGirish Moodalbail 646e91bba0SGirish Moodalbail typedef struct cmd { 656e91bba0SGirish Moodalbail char *c_name; 666e91bba0SGirish Moodalbail cmdfunc_t *c_fn; 676e91bba0SGirish Moodalbail const char *c_usage; 686e91bba0SGirish Moodalbail } cmd_t; 696e91bba0SGirish Moodalbail 706e91bba0SGirish Moodalbail static cmd_t cmds[] = { 716e91bba0SGirish Moodalbail /* interface management related sub-commands */ 726e91bba0SGirish Moodalbail { "create-if", do_create_if, "\tcreate-if\t[-t] <interface>" }, 736e91bba0SGirish Moodalbail { "disable-if", do_disable_if, "\tdisable-if\t-t <interface>" }, 746e91bba0SGirish Moodalbail { "enable-if", do_enable_if, "\tenable-if\t-t <interface>" }, 756e91bba0SGirish Moodalbail { "delete-if", do_delete_if, "\tdelete-if\t<interface>" }, 766e91bba0SGirish Moodalbail { "show-if", do_show_if, 776e91bba0SGirish Moodalbail "\tshow-if\t\t[[-p] -o <field>,...] [<interface>]\n" }, 786e91bba0SGirish Moodalbail { "set-ifprop", do_set_ifprop, 796e91bba0SGirish Moodalbail "\tset-ifprop\t[-t] -p <prop>=<value[,...]> -m <protocol> " 806e91bba0SGirish Moodalbail "<interface>" }, 816e91bba0SGirish Moodalbail { "reset-ifprop", do_reset_ifprop, 826e91bba0SGirish Moodalbail "\treset-ifprop\t[-t] -p <prop> -m <protocol> <interface>" }, 836e91bba0SGirish Moodalbail { "show-ifprop", do_show_ifprop, 846e91bba0SGirish Moodalbail "\tshow-ifprop\t[[-c] -o <field>,...] [-p <prop>,...]\n" 856e91bba0SGirish Moodalbail "\t\t\t[-m <protocol>] [interface]\n" }, 866e91bba0SGirish Moodalbail 876e91bba0SGirish Moodalbail /* address management related sub-commands */ 886e91bba0SGirish Moodalbail { "create-addr", do_create_addr, 89*7bc87895SYuri Pankov "\tcreate-addr\t[-t] -T static [-d] " 90*7bc87895SYuri Pankov "-a{local|remote}=addr[/prefixlen]\n\t\t\t<addrobj>\n" 91*7bc87895SYuri Pankov "\tcreate-addr\t[-t] -T dhcp [-w <seconds> | forever] <addrobj>\n" 92*7bc87895SYuri Pankov "\tcreate-addr\t[-t] -T addrconf [-i interface-id]\n" 93*7bc87895SYuri Pankov "\t\t\t[-p {stateful|stateless}={yes|no}] <addrobj>" }, 946e91bba0SGirish Moodalbail { "down-addr", do_down_addr, "\tdown-addr\t[-t] <addrobj>" }, 956e91bba0SGirish Moodalbail { "up-addr", do_up_addr, "\tup-addr\t\t[-t] <addrobj>" }, 966e91bba0SGirish Moodalbail { "disable-addr", do_disable_addr, "\tdisable-addr\t-t <addrobj>" }, 976e91bba0SGirish Moodalbail { "enable-addr", do_enable_addr, "\tenable-addr\t-t <addrobj>" }, 986e91bba0SGirish Moodalbail { "refresh-addr", do_refresh_addr, "\trefresh-addr\t[-i] <addrobj>" }, 996e91bba0SGirish Moodalbail { "delete-addr", do_delete_addr, "\tdelete-addr\t[-r] <addrobj>" }, 1006e91bba0SGirish Moodalbail { "show-addr", do_show_addr, 1016e91bba0SGirish Moodalbail "\tshow-addr\t[[-p] -o <field>,...] [<addrobj>]\n" }, 1026e91bba0SGirish Moodalbail { "set-addrprop", do_set_addrprop, 1036e91bba0SGirish Moodalbail "\tset-addrprop\t[-t] -p <prop>=<value[,...]> <addrobj>" }, 1046e91bba0SGirish Moodalbail { "reset-addrprop", do_reset_addrprop, 1056e91bba0SGirish Moodalbail "\treset-addrprop\t[-t] -p <prop> <addrobj>" }, 1066e91bba0SGirish Moodalbail { "show-addrprop", do_show_addrprop, 1076e91bba0SGirish Moodalbail "\tshow-addrprop\t[[-c] -o <field>,...] [-p <prop>,...] " 1086e91bba0SGirish Moodalbail "<addrobj>\n" }, 1096e91bba0SGirish Moodalbail 1106e91bba0SGirish Moodalbail /* protocol properties related sub-commands */ 1116e91bba0SGirish Moodalbail { "set-prop", do_set_prop, 1126e91bba0SGirish Moodalbail "\tset-prop\t[-t] -p <prop>[+|-]=<value[,...]> <protocol>" }, 1136e91bba0SGirish Moodalbail { "reset-prop", do_reset_prop, 1146e91bba0SGirish Moodalbail "\treset-prop\t[-t] -p <prop> <protocol>" }, 1156e91bba0SGirish Moodalbail { "show-prop", do_show_prop, 1166e91bba0SGirish Moodalbail "\tshow-prop\t[[-c] -o <field>,...] [-p <prop>,...]" 1178887b57dSGirish Moodalbail " [protocol]" } 1186e91bba0SGirish Moodalbail }; 1196e91bba0SGirish Moodalbail 1206e91bba0SGirish Moodalbail static const struct option if_longopts[] = { 1216e91bba0SGirish Moodalbail {"temporary", no_argument, 0, 't' }, 1226e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1236e91bba0SGirish Moodalbail }; 1246e91bba0SGirish Moodalbail 1256e91bba0SGirish Moodalbail static const struct option show_prop_longopts[] = { 1266e91bba0SGirish Moodalbail {"parsable", no_argument, 0, 'c' }, 1276e91bba0SGirish Moodalbail {"prop", required_argument, 0, 'p' }, 1286e91bba0SGirish Moodalbail {"output", required_argument, 0, 'o' }, 1296e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1306e91bba0SGirish Moodalbail }; 1316e91bba0SGirish Moodalbail 1326e91bba0SGirish Moodalbail static const struct option show_ifprop_longopts[] = { 1336e91bba0SGirish Moodalbail {"module", required_argument, 0, 'm' }, 1346e91bba0SGirish Moodalbail {"parsable", no_argument, 0, 'c' }, 1356e91bba0SGirish Moodalbail {"prop", required_argument, 0, 'p' }, 1366e91bba0SGirish Moodalbail {"output", required_argument, 0, 'o' }, 1376e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1386e91bba0SGirish Moodalbail }; 1396e91bba0SGirish Moodalbail 1406e91bba0SGirish Moodalbail static const struct option set_prop_longopts[] = { 1416e91bba0SGirish Moodalbail {"prop", required_argument, 0, 'p' }, 1426e91bba0SGirish Moodalbail {"temporary", no_argument, 0, 't' }, 1436e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1446e91bba0SGirish Moodalbail }; 1456e91bba0SGirish Moodalbail 1466e91bba0SGirish Moodalbail static const struct option set_ifprop_longopts[] = { 1476e91bba0SGirish Moodalbail {"module", required_argument, 0, 'm' }, 1486e91bba0SGirish Moodalbail {"prop", required_argument, 0, 'p' }, 1496e91bba0SGirish Moodalbail {"temporary", no_argument, 0, 't' }, 1506e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1516e91bba0SGirish Moodalbail }; 1526e91bba0SGirish Moodalbail 1536e91bba0SGirish Moodalbail static const struct option addr_misc_longopts[] = { 1546e91bba0SGirish Moodalbail {"inform", no_argument, 0, 'i' }, 1556e91bba0SGirish Moodalbail {"release", no_argument, 0, 'r' }, 1566e91bba0SGirish Moodalbail {"temporary", no_argument, 0, 't' }, 1576e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1586e91bba0SGirish Moodalbail }; 1596e91bba0SGirish Moodalbail 1606e91bba0SGirish Moodalbail static const struct option addr_longopts[] = { 1616e91bba0SGirish Moodalbail {"address", required_argument, 0, 'a' }, 1626e91bba0SGirish Moodalbail {"down", no_argument, 0, 'd' }, 1636e91bba0SGirish Moodalbail {"interface-id", required_argument, 0, 'i' }, 1646e91bba0SGirish Moodalbail {"prop", required_argument, 0, 'p' }, 1656e91bba0SGirish Moodalbail {"temporary", no_argument, 0, 't' }, 1666e91bba0SGirish Moodalbail {"type", required_argument, 0, 'T' }, 1676e91bba0SGirish Moodalbail {"wait", required_argument, 0, 'w' }, 1686e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1696e91bba0SGirish Moodalbail }; 1706e91bba0SGirish Moodalbail 1716e91bba0SGirish Moodalbail static const struct option show_addr_longopts[] = { 1726e91bba0SGirish Moodalbail {"parsable", no_argument, 0, 'p' }, 1736e91bba0SGirish Moodalbail {"output", required_argument, 0, 'o' }, 1746e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1756e91bba0SGirish Moodalbail }; 1766e91bba0SGirish Moodalbail 1776e91bba0SGirish Moodalbail static const struct option show_if_longopts[] = { 1786e91bba0SGirish Moodalbail {"parsable", no_argument, 0, 'p' }, 1796e91bba0SGirish Moodalbail {"output", required_argument, 0, 'o' }, 1806e91bba0SGirish Moodalbail { 0, 0, 0, 0 } 1816e91bba0SGirish Moodalbail }; 1826e91bba0SGirish Moodalbail 1836e91bba0SGirish Moodalbail /* callback functions to print show-* subcommands output */ 1846e91bba0SGirish Moodalbail static ofmt_cb_t print_prop_cb; 1856e91bba0SGirish Moodalbail static ofmt_cb_t print_sa_cb; 1866e91bba0SGirish Moodalbail static ofmt_cb_t print_si_cb; 1876e91bba0SGirish Moodalbail 1886e91bba0SGirish Moodalbail /* structures for 'ipadm show-*' subcommands */ 1896e91bba0SGirish Moodalbail typedef enum { 1906e91bba0SGirish Moodalbail IPADM_PROPFIELD_IFNAME, 1916e91bba0SGirish Moodalbail IPADM_PROPFIELD_PROTO, 1926e91bba0SGirish Moodalbail IPADM_PROPFIELD_ADDROBJ, 1936e91bba0SGirish Moodalbail IPADM_PROPFIELD_PROPERTY, 1946e91bba0SGirish Moodalbail IPADM_PROPFIELD_PERM, 1956e91bba0SGirish Moodalbail IPADM_PROPFIELD_CURRENT, 1966e91bba0SGirish Moodalbail IPADM_PROPFIELD_PERSISTENT, 1976e91bba0SGirish Moodalbail IPADM_PROPFIELD_DEFAULT, 1986e91bba0SGirish Moodalbail IPADM_PROPFIELD_POSSIBLE 1996e91bba0SGirish Moodalbail } ipadm_propfield_index_t; 2006e91bba0SGirish Moodalbail 2016e91bba0SGirish Moodalbail static ofmt_field_t intfprop_fields[] = { 2026e91bba0SGirish Moodalbail /* name, field width, index, callback */ 2036e91bba0SGirish Moodalbail { "IFNAME", 12, IPADM_PROPFIELD_IFNAME, print_prop_cb}, 2046e91bba0SGirish Moodalbail { "PROPERTY", 16, IPADM_PROPFIELD_PROPERTY, print_prop_cb}, 2056e91bba0SGirish Moodalbail { "PROTO", 6, IPADM_PROPFIELD_PROTO, print_prop_cb}, 2066e91bba0SGirish Moodalbail { "PERM", 5, IPADM_PROPFIELD_PERM, print_prop_cb}, 2076e91bba0SGirish Moodalbail { "CURRENT", 11, IPADM_PROPFIELD_CURRENT, print_prop_cb}, 2086e91bba0SGirish Moodalbail { "PERSISTENT", 11, IPADM_PROPFIELD_PERSISTENT, print_prop_cb}, 2096e91bba0SGirish Moodalbail { "DEFAULT", 11, IPADM_PROPFIELD_DEFAULT, print_prop_cb}, 2106e91bba0SGirish Moodalbail { "POSSIBLE", 16, IPADM_PROPFIELD_POSSIBLE, print_prop_cb}, 2116e91bba0SGirish Moodalbail { NULL, 0, 0, NULL} 2126e91bba0SGirish Moodalbail }; 2136e91bba0SGirish Moodalbail 2146e91bba0SGirish Moodalbail 2156e91bba0SGirish Moodalbail static ofmt_field_t modprop_fields[] = { 2166e91bba0SGirish Moodalbail /* name, field width, index, callback */ 2176e91bba0SGirish Moodalbail { "PROTO", 6, IPADM_PROPFIELD_PROTO, print_prop_cb}, 2186e91bba0SGirish Moodalbail { "PROPERTY", 22, IPADM_PROPFIELD_PROPERTY, print_prop_cb}, 2196e91bba0SGirish Moodalbail { "PERM", 5, IPADM_PROPFIELD_PERM, print_prop_cb}, 2206e91bba0SGirish Moodalbail { "CURRENT", 13, IPADM_PROPFIELD_CURRENT, print_prop_cb}, 2216e91bba0SGirish Moodalbail { "PERSISTENT", 13, IPADM_PROPFIELD_PERSISTENT, print_prop_cb}, 2226e91bba0SGirish Moodalbail { "DEFAULT", 13, IPADM_PROPFIELD_DEFAULT, print_prop_cb}, 2236e91bba0SGirish Moodalbail { "POSSIBLE", 15, IPADM_PROPFIELD_POSSIBLE, print_prop_cb}, 2246e91bba0SGirish Moodalbail { NULL, 0, 0, NULL} 2256e91bba0SGirish Moodalbail }; 2266e91bba0SGirish Moodalbail 2276e91bba0SGirish Moodalbail static ofmt_field_t addrprop_fields[] = { 2286e91bba0SGirish Moodalbail /* name, field width, index, callback */ 2296e91bba0SGirish Moodalbail { "ADDROBJ", 18, IPADM_PROPFIELD_ADDROBJ, print_prop_cb}, 2306e91bba0SGirish Moodalbail { "PROPERTY", 11, IPADM_PROPFIELD_PROPERTY, print_prop_cb}, 2316e91bba0SGirish Moodalbail { "PERM", 5, IPADM_PROPFIELD_PERM, print_prop_cb}, 2326e91bba0SGirish Moodalbail { "CURRENT", 16, IPADM_PROPFIELD_CURRENT, print_prop_cb}, 2336e91bba0SGirish Moodalbail { "PERSISTENT", 16, IPADM_PROPFIELD_PERSISTENT, print_prop_cb}, 2346e91bba0SGirish Moodalbail { "DEFAULT", 16, IPADM_PROPFIELD_DEFAULT, print_prop_cb}, 2356e91bba0SGirish Moodalbail { "POSSIBLE", 15, IPADM_PROPFIELD_POSSIBLE, print_prop_cb}, 2366e91bba0SGirish Moodalbail { NULL, 0, 0, NULL} 2376e91bba0SGirish Moodalbail }; 2386e91bba0SGirish Moodalbail 2396e91bba0SGirish Moodalbail typedef struct show_prop_state { 2406e91bba0SGirish Moodalbail char sps_ifname[LIFNAMSIZ]; 2416e91bba0SGirish Moodalbail char sps_aobjname[IPADM_AOBJSIZ]; 2426e91bba0SGirish Moodalbail const char *sps_pname; 2436e91bba0SGirish Moodalbail uint_t sps_proto; 2446e91bba0SGirish Moodalbail char *sps_propval; 2456e91bba0SGirish Moodalbail nvlist_t *sps_proplist; 2466e91bba0SGirish Moodalbail boolean_t sps_parsable; 2476e91bba0SGirish Moodalbail boolean_t sps_addrprop; 2486e91bba0SGirish Moodalbail boolean_t sps_ifprop; 2496e91bba0SGirish Moodalbail boolean_t sps_modprop; 2506e91bba0SGirish Moodalbail ipadm_status_t sps_status; 2516e91bba0SGirish Moodalbail ipadm_status_t sps_retstatus; 2526e91bba0SGirish Moodalbail ofmt_handle_t sps_ofmt; 2536e91bba0SGirish Moodalbail } show_prop_state_t; 2546e91bba0SGirish Moodalbail 2556e91bba0SGirish Moodalbail typedef struct show_addr_state { 2566e91bba0SGirish Moodalbail boolean_t sa_parsable; 2576e91bba0SGirish Moodalbail boolean_t sa_persist; 2586e91bba0SGirish Moodalbail ofmt_handle_t sa_ofmt; 2596e91bba0SGirish Moodalbail } show_addr_state_t; 2606e91bba0SGirish Moodalbail 2616e91bba0SGirish Moodalbail typedef struct show_if_state { 2626e91bba0SGirish Moodalbail boolean_t si_parsable; 2636e91bba0SGirish Moodalbail ofmt_handle_t si_ofmt; 2646e91bba0SGirish Moodalbail } show_if_state_t; 2656e91bba0SGirish Moodalbail 2666e91bba0SGirish Moodalbail typedef struct show_addr_args_s { 2676e91bba0SGirish Moodalbail show_addr_state_t *sa_state; 2686e91bba0SGirish Moodalbail ipadm_addr_info_t *sa_info; 2696e91bba0SGirish Moodalbail } show_addr_args_t; 2706e91bba0SGirish Moodalbail 2716e91bba0SGirish Moodalbail typedef struct show_if_args_s { 2726e91bba0SGirish Moodalbail show_if_state_t *si_state; 2736e91bba0SGirish Moodalbail ipadm_if_info_t *si_info; 2746e91bba0SGirish Moodalbail } show_if_args_t; 2756e91bba0SGirish Moodalbail 2766e91bba0SGirish Moodalbail typedef enum { 2776e91bba0SGirish Moodalbail SA_ADDROBJ, 2786e91bba0SGirish Moodalbail SA_TYPE, 2796e91bba0SGirish Moodalbail SA_STATE, 2806e91bba0SGirish Moodalbail SA_CURRENT, 2816e91bba0SGirish Moodalbail SA_PERSISTENT, 2826e91bba0SGirish Moodalbail SA_ADDR 2836e91bba0SGirish Moodalbail } sa_field_index_t; 2846e91bba0SGirish Moodalbail 2856e91bba0SGirish Moodalbail typedef enum { 2866e91bba0SGirish Moodalbail SI_IFNAME, 2876e91bba0SGirish Moodalbail SI_STATE, 2886e91bba0SGirish Moodalbail SI_CURRENT, 2896e91bba0SGirish Moodalbail SI_PERSISTENT 2906e91bba0SGirish Moodalbail } si_field_index_t; 2916e91bba0SGirish Moodalbail 2926e91bba0SGirish Moodalbail static ofmt_field_t show_addr_fields[] = { 2936e91bba0SGirish Moodalbail /* name, field width, id, callback */ 2946e91bba0SGirish Moodalbail { "ADDROBJ", 18, SA_ADDROBJ, print_sa_cb}, 2956e91bba0SGirish Moodalbail { "TYPE", 9, SA_TYPE, print_sa_cb}, 2966e91bba0SGirish Moodalbail { "STATE", 13, SA_STATE, print_sa_cb}, 2976e91bba0SGirish Moodalbail { "CURRENT", 8, SA_CURRENT, print_sa_cb}, 2986e91bba0SGirish Moodalbail { "PERSISTENT", 11, SA_PERSISTENT, print_sa_cb}, 2996e91bba0SGirish Moodalbail { "ADDR", 46, SA_ADDR, print_sa_cb}, 3006e91bba0SGirish Moodalbail { NULL, 0, 0, NULL} 3016e91bba0SGirish Moodalbail }; 3026e91bba0SGirish Moodalbail 3036e91bba0SGirish Moodalbail static ofmt_field_t show_if_fields[] = { 3046e91bba0SGirish Moodalbail /* name, field width, id, callback */ 3056e91bba0SGirish Moodalbail { "IFNAME", 11, SI_IFNAME, print_si_cb}, 3066e91bba0SGirish Moodalbail { "STATE", 9, SI_STATE, print_si_cb}, 307550b6e40SSowmini Varadhan { "CURRENT", 13, SI_CURRENT, print_si_cb}, 3086e91bba0SGirish Moodalbail { "PERSISTENT", 11, SI_PERSISTENT, print_si_cb}, 3096e91bba0SGirish Moodalbail { NULL, 0, 0, NULL} 3106e91bba0SGirish Moodalbail }; 3116e91bba0SGirish Moodalbail 3126e91bba0SGirish Moodalbail #define IPADM_ALL_BITS ((uint_t)-1) 3136e91bba0SGirish Moodalbail typedef struct intf_mask { 3146e91bba0SGirish Moodalbail char *name; 3156e91bba0SGirish Moodalbail uint64_t bits; 3166e91bba0SGirish Moodalbail uint64_t mask; 3176e91bba0SGirish Moodalbail } fmask_t; 3186e91bba0SGirish Moodalbail 3196e91bba0SGirish Moodalbail /* 3206e91bba0SGirish Moodalbail * Handle to libipadm. Opened in main() before the sub-command specific 3216e91bba0SGirish Moodalbail * function is called and is closed before the program exits. 3226e91bba0SGirish Moodalbail */ 3236e91bba0SGirish Moodalbail ipadm_handle_t iph = NULL; 3246e91bba0SGirish Moodalbail 3256e91bba0SGirish Moodalbail /* 3266e91bba0SGirish Moodalbail * Opaque ipadm address object. Used by all the address management subcommands. 3276e91bba0SGirish Moodalbail */ 3286e91bba0SGirish Moodalbail ipadm_addrobj_t ipaddr = NULL; 3296e91bba0SGirish Moodalbail 3306e91bba0SGirish Moodalbail static char *progname; 3316e91bba0SGirish Moodalbail 3326e91bba0SGirish Moodalbail static void die(const char *, ...); 3336e91bba0SGirish Moodalbail static void die_opterr(int, int, const char *); 3346e91bba0SGirish Moodalbail static void warn_ipadmerr(ipadm_status_t, const char *, ...); 3356e91bba0SGirish Moodalbail static void ipadm_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t); 3366e91bba0SGirish Moodalbail static void ipadm_check_propstr(const char *, boolean_t, const char *); 3376e91bba0SGirish Moodalbail static void process_misc_addrargs(int, char **, const char *, int *, 3386e91bba0SGirish Moodalbail uint32_t *); 3396e91bba0SGirish Moodalbail 3406e91bba0SGirish Moodalbail static void 3416e91bba0SGirish Moodalbail usage(void) 3426e91bba0SGirish Moodalbail { 3436e91bba0SGirish Moodalbail int i; 3446e91bba0SGirish Moodalbail cmd_t *cmdp; 3456e91bba0SGirish Moodalbail 3466e91bba0SGirish Moodalbail (void) fprintf(stderr, 3476e91bba0SGirish Moodalbail gettext("usage: ipadm <subcommand> <args> ...\n")); 3486e91bba0SGirish Moodalbail for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) { 3496e91bba0SGirish Moodalbail cmdp = &cmds[i]; 3506e91bba0SGirish Moodalbail if (cmdp->c_usage != NULL) 3516e91bba0SGirish Moodalbail (void) fprintf(stderr, "%s\n", gettext(cmdp->c_usage)); 3526e91bba0SGirish Moodalbail } 3536e91bba0SGirish Moodalbail 3546e91bba0SGirish Moodalbail ipadm_destroy_addrobj(ipaddr); 3556e91bba0SGirish Moodalbail ipadm_close(iph); 3566e91bba0SGirish Moodalbail exit(1); 3576e91bba0SGirish Moodalbail } 3586e91bba0SGirish Moodalbail 3596e91bba0SGirish Moodalbail int 3606e91bba0SGirish Moodalbail main(int argc, char *argv[]) 3616e91bba0SGirish Moodalbail { 3626e91bba0SGirish Moodalbail int i; 3636e91bba0SGirish Moodalbail cmd_t *cmdp; 3646e91bba0SGirish Moodalbail ipadm_status_t status; 3656e91bba0SGirish Moodalbail 3666e91bba0SGirish Moodalbail (void) setlocale(LC_ALL, ""); 3676e91bba0SGirish Moodalbail (void) textdomain(TEXT_DOMAIN); 3686e91bba0SGirish Moodalbail 3696e91bba0SGirish Moodalbail if ((progname = strrchr(argv[0], '/')) == NULL) 3706e91bba0SGirish Moodalbail progname = argv[0]; 3716e91bba0SGirish Moodalbail else 3726e91bba0SGirish Moodalbail progname++; 3736e91bba0SGirish Moodalbail 3746e91bba0SGirish Moodalbail if (argc < 2) 3756e91bba0SGirish Moodalbail usage(); 3766e91bba0SGirish Moodalbail 3776e91bba0SGirish Moodalbail status = ipadm_open(&iph, 0); 3786e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 3796e91bba0SGirish Moodalbail die("Could not open handle to library - %s", 3806e91bba0SGirish Moodalbail ipadm_status2str(status)); 3816e91bba0SGirish Moodalbail } 3826e91bba0SGirish Moodalbail 3836e91bba0SGirish Moodalbail for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) { 3846e91bba0SGirish Moodalbail cmdp = &cmds[i]; 3856e91bba0SGirish Moodalbail if (strcmp(argv[1], cmdp->c_name) == 0) { 3866e91bba0SGirish Moodalbail cmdp->c_fn(argc - 1, &argv[1], gettext(cmdp->c_usage)); 3876e91bba0SGirish Moodalbail ipadm_destroy_addrobj(ipaddr); 3886e91bba0SGirish Moodalbail ipadm_close(iph); 3896e91bba0SGirish Moodalbail exit(0); 3906e91bba0SGirish Moodalbail } 3916e91bba0SGirish Moodalbail } 3926e91bba0SGirish Moodalbail 3936e91bba0SGirish Moodalbail (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"), 3946e91bba0SGirish Moodalbail progname, argv[1]); 3956e91bba0SGirish Moodalbail usage(); 3966e91bba0SGirish Moodalbail 3976e91bba0SGirish Moodalbail return (0); 3986e91bba0SGirish Moodalbail } 3996e91bba0SGirish Moodalbail 4006e91bba0SGirish Moodalbail /* 4016e91bba0SGirish Moodalbail * Create an IP interface for which no saved configuration exists in the 4026e91bba0SGirish Moodalbail * persistent store. 4036e91bba0SGirish Moodalbail */ 4046e91bba0SGirish Moodalbail static void 4056e91bba0SGirish Moodalbail do_create_if(int argc, char *argv[], const char *use) 4066e91bba0SGirish Moodalbail { 4076e91bba0SGirish Moodalbail ipadm_status_t status; 4086e91bba0SGirish Moodalbail int option; 4096e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_PERSIST|IPADM_OPT_ACTIVE; 4106e91bba0SGirish Moodalbail 4116e91bba0SGirish Moodalbail opterr = 0; 4126e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":t", if_longopts, 4136e91bba0SGirish Moodalbail NULL)) != -1) { 4146e91bba0SGirish Moodalbail switch (option) { 4156e91bba0SGirish Moodalbail case 't': 4166e91bba0SGirish Moodalbail /* 4176e91bba0SGirish Moodalbail * "ifconfig" mode - plumb interface, but do not 4186e91bba0SGirish Moodalbail * restore settings that may exist in db. 4196e91bba0SGirish Moodalbail */ 4206e91bba0SGirish Moodalbail flags &= ~IPADM_OPT_PERSIST; 4216e91bba0SGirish Moodalbail break; 4226e91bba0SGirish Moodalbail default: 4236e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 4246e91bba0SGirish Moodalbail } 4256e91bba0SGirish Moodalbail } 4266e91bba0SGirish Moodalbail if (optind != (argc - 1)) 4276e91bba0SGirish Moodalbail die("Usage: %s", use); 4286e91bba0SGirish Moodalbail status = ipadm_create_if(iph, argv[optind], AF_UNSPEC, flags); 4296e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 4306e91bba0SGirish Moodalbail die("Could not create %s : %s", 4316e91bba0SGirish Moodalbail argv[optind], ipadm_status2str(status)); 4326e91bba0SGirish Moodalbail } 4336e91bba0SGirish Moodalbail } 4346e91bba0SGirish Moodalbail 4356e91bba0SGirish Moodalbail /* 4366e91bba0SGirish Moodalbail * Enable an IP interface based on the persistent configuration for 4376e91bba0SGirish Moodalbail * that interface. 4386e91bba0SGirish Moodalbail */ 4396e91bba0SGirish Moodalbail static void 4406e91bba0SGirish Moodalbail do_enable_if(int argc, char *argv[], const char *use) 4416e91bba0SGirish Moodalbail { 4426e91bba0SGirish Moodalbail ipadm_status_t status; 4436e91bba0SGirish Moodalbail int index; 4446e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 4456e91bba0SGirish Moodalbail 4466e91bba0SGirish Moodalbail process_misc_addrargs(argc, argv, use, &index, &flags); 4476e91bba0SGirish Moodalbail if (flags & IPADM_OPT_PERSIST) 4486e91bba0SGirish Moodalbail die("persistent operation not supported for enable-if"); 4496e91bba0SGirish Moodalbail status = ipadm_enable_if(iph, argv[index], flags); 4506e91bba0SGirish Moodalbail if (status == IPADM_ALL_ADDRS_NOT_ENABLED) { 4516e91bba0SGirish Moodalbail warn_ipadmerr(status, ""); 4526e91bba0SGirish Moodalbail } else if (status != IPADM_SUCCESS) { 4536e91bba0SGirish Moodalbail die("Could not enable %s : %s", 4546e91bba0SGirish Moodalbail argv[optind], ipadm_status2str(status)); 4556e91bba0SGirish Moodalbail } 4566e91bba0SGirish Moodalbail } 4576e91bba0SGirish Moodalbail 4586e91bba0SGirish Moodalbail /* 4596e91bba0SGirish Moodalbail * Remove an IP interface from both active and persistent configuration. 4606e91bba0SGirish Moodalbail */ 4616e91bba0SGirish Moodalbail static void 4626e91bba0SGirish Moodalbail do_delete_if(int argc, char *argv[], const char *use) 4636e91bba0SGirish Moodalbail { 4646e91bba0SGirish Moodalbail ipadm_status_t status; 4656e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 4666e91bba0SGirish Moodalbail 4676e91bba0SGirish Moodalbail if (argc != 2) 4686e91bba0SGirish Moodalbail die("Usage: %s", use); 4696e91bba0SGirish Moodalbail 4706e91bba0SGirish Moodalbail status = ipadm_delete_if(iph, argv[1], AF_UNSPEC, flags); 4716e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 4726e91bba0SGirish Moodalbail die("Could not delete %s: %s", 4736e91bba0SGirish Moodalbail argv[optind], ipadm_status2str(status)); 4746e91bba0SGirish Moodalbail } 4756e91bba0SGirish Moodalbail } 4766e91bba0SGirish Moodalbail 4776e91bba0SGirish Moodalbail /* 4786e91bba0SGirish Moodalbail * Disable an IP interface by removing it from active configuration. 4796e91bba0SGirish Moodalbail */ 4806e91bba0SGirish Moodalbail static void 4816e91bba0SGirish Moodalbail do_disable_if(int argc, char *argv[], const char *use) 4826e91bba0SGirish Moodalbail { 4836e91bba0SGirish Moodalbail ipadm_status_t status; 4846e91bba0SGirish Moodalbail int index; 4856e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 4866e91bba0SGirish Moodalbail 4876e91bba0SGirish Moodalbail process_misc_addrargs(argc, argv, use, &index, &flags); 4886e91bba0SGirish Moodalbail if (flags & IPADM_OPT_PERSIST) 4896e91bba0SGirish Moodalbail die("persistent operation not supported for disable-if"); 4906e91bba0SGirish Moodalbail status = ipadm_disable_if(iph, argv[index], flags); 4916e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 4926e91bba0SGirish Moodalbail die("Could not disable %s: %s", 4936e91bba0SGirish Moodalbail argv[optind], ipadm_status2str(status)); 4946e91bba0SGirish Moodalbail } 4956e91bba0SGirish Moodalbail } 4966e91bba0SGirish Moodalbail 4976e91bba0SGirish Moodalbail /* 4986e91bba0SGirish Moodalbail * called in from print_prop_cb() and does the job of printing each 4996e91bba0SGirish Moodalbail * individual column in the 'ipadm show-*prop' output. 5006e91bba0SGirish Moodalbail */ 5016e91bba0SGirish Moodalbail static void 5026e91bba0SGirish Moodalbail print_prop(show_prop_state_t *statep, uint_t flags, char *buf, size_t bufsize) 5036e91bba0SGirish Moodalbail { 5046e91bba0SGirish Moodalbail const char *prop_name = statep->sps_pname; 5056e91bba0SGirish Moodalbail char *ifname = statep->sps_ifname; 5066e91bba0SGirish Moodalbail char *propval = statep->sps_propval; 5076e91bba0SGirish Moodalbail uint_t proto = statep->sps_proto; 5086e91bba0SGirish Moodalbail size_t propsize = MAXPROPVALLEN; 5096e91bba0SGirish Moodalbail char *object; 5106e91bba0SGirish Moodalbail ipadm_status_t status; 5116e91bba0SGirish Moodalbail 5126e91bba0SGirish Moodalbail if (statep->sps_ifprop) { 5136e91bba0SGirish Moodalbail status = ipadm_get_ifprop(iph, ifname, prop_name, propval, 5146e91bba0SGirish Moodalbail &propsize, proto, flags); 5156e91bba0SGirish Moodalbail object = ifname; 5166e91bba0SGirish Moodalbail } else if (statep->sps_modprop) { 5176e91bba0SGirish Moodalbail status = ipadm_get_prop(iph, prop_name, propval, &propsize, 5186e91bba0SGirish Moodalbail proto, flags); 5196e91bba0SGirish Moodalbail object = ipadm_proto2str(proto); 5206e91bba0SGirish Moodalbail } else { 5216e91bba0SGirish Moodalbail status = ipadm_get_addrprop(iph, prop_name, propval, &propsize, 5226e91bba0SGirish Moodalbail statep->sps_aobjname, flags); 5236e91bba0SGirish Moodalbail object = statep->sps_aobjname; 5246e91bba0SGirish Moodalbail } 5256e91bba0SGirish Moodalbail 5266e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 5276e91bba0SGirish Moodalbail if (status == IPADM_PROP_UNKNOWN || 5286e91bba0SGirish Moodalbail status == IPADM_INVALID_ARG) { 5296e91bba0SGirish Moodalbail warn_ipadmerr(status, "cannot get property '%s' for " 5306e91bba0SGirish Moodalbail "'%s'", prop_name, object); 5316e91bba0SGirish Moodalbail } else if (status == IPADM_NOTSUP) { 5326e91bba0SGirish Moodalbail warn_ipadmerr(status, "'%s'", object); 5336e91bba0SGirish Moodalbail } else if (status == IPADM_NOTFOUND) { 5346e91bba0SGirish Moodalbail if (flags & IPADM_OPT_PERSIST) { 5356e91bba0SGirish Moodalbail propval[0] = '\0'; 5366e91bba0SGirish Moodalbail goto cont; 5376e91bba0SGirish Moodalbail } else { 5386e91bba0SGirish Moodalbail warn_ipadmerr(status, "no such object '%s'", 5396e91bba0SGirish Moodalbail object); 5406e91bba0SGirish Moodalbail } 5416e91bba0SGirish Moodalbail } else if (status == IPADM_ENXIO) { 5426e91bba0SGirish Moodalbail /* the interface is probably disabled */ 5436e91bba0SGirish Moodalbail propval[0] = '\0'; 5446e91bba0SGirish Moodalbail goto cont; 5456e91bba0SGirish Moodalbail } 5466e91bba0SGirish Moodalbail statep->sps_status = status; 5476e91bba0SGirish Moodalbail statep->sps_retstatus = status; 5486e91bba0SGirish Moodalbail return; 5496e91bba0SGirish Moodalbail } 5506e91bba0SGirish Moodalbail cont: 5516e91bba0SGirish Moodalbail statep->sps_status = IPADM_SUCCESS; 5526e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s", propval); 5536e91bba0SGirish Moodalbail } 5546e91bba0SGirish Moodalbail 5556e91bba0SGirish Moodalbail /* 5566e91bba0SGirish Moodalbail * callback function which displays output for set-prop, set-ifprop and 5576e91bba0SGirish Moodalbail * set-addrprop subcommands. 5586e91bba0SGirish Moodalbail */ 5596e91bba0SGirish Moodalbail static boolean_t 5606e91bba0SGirish Moodalbail print_prop_cb(ofmt_arg_t *ofarg, char *buf, size_t bufsize) 5616e91bba0SGirish Moodalbail { 5626e91bba0SGirish Moodalbail show_prop_state_t *statep = ofarg->ofmt_cbarg; 5636e91bba0SGirish Moodalbail const char *propname = statep->sps_pname; 5646e91bba0SGirish Moodalbail uint_t proto = statep->sps_proto; 5656e91bba0SGirish Moodalbail boolean_t cont = _B_TRUE; 5666e91bba0SGirish Moodalbail 5676e91bba0SGirish Moodalbail /* 5686e91bba0SGirish Moodalbail * Fail retrieving remaining fields, if you fail 5696e91bba0SGirish Moodalbail * to retrieve a field. 5706e91bba0SGirish Moodalbail */ 5716e91bba0SGirish Moodalbail if (statep->sps_status != IPADM_SUCCESS) 5726e91bba0SGirish Moodalbail return (_B_FALSE); 5736e91bba0SGirish Moodalbail 5746e91bba0SGirish Moodalbail switch (ofarg->ofmt_id) { 5756e91bba0SGirish Moodalbail case IPADM_PROPFIELD_IFNAME: 5766e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s", statep->sps_ifname); 5776e91bba0SGirish Moodalbail break; 5786e91bba0SGirish Moodalbail case IPADM_PROPFIELD_PROTO: 5796e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s", ipadm_proto2str(proto)); 5806e91bba0SGirish Moodalbail break; 5816e91bba0SGirish Moodalbail case IPADM_PROPFIELD_ADDROBJ: 5826e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s", statep->sps_aobjname); 5836e91bba0SGirish Moodalbail break; 5846e91bba0SGirish Moodalbail case IPADM_PROPFIELD_PROPERTY: 5856e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s", propname); 5866e91bba0SGirish Moodalbail break; 5876e91bba0SGirish Moodalbail case IPADM_PROPFIELD_PERM: 5886e91bba0SGirish Moodalbail print_prop(statep, IPADM_OPT_PERM, buf, bufsize); 5896e91bba0SGirish Moodalbail break; 5906e91bba0SGirish Moodalbail case IPADM_PROPFIELD_CURRENT: 5916e91bba0SGirish Moodalbail print_prop(statep, IPADM_OPT_ACTIVE, buf, bufsize); 5926e91bba0SGirish Moodalbail break; 5936e91bba0SGirish Moodalbail case IPADM_PROPFIELD_PERSISTENT: 5946e91bba0SGirish Moodalbail print_prop(statep, IPADM_OPT_PERSIST, buf, bufsize); 5956e91bba0SGirish Moodalbail break; 5966e91bba0SGirish Moodalbail case IPADM_PROPFIELD_DEFAULT: 5976e91bba0SGirish Moodalbail print_prop(statep, IPADM_OPT_DEFAULT, buf, bufsize); 5986e91bba0SGirish Moodalbail break; 5996e91bba0SGirish Moodalbail case IPADM_PROPFIELD_POSSIBLE: 6006e91bba0SGirish Moodalbail print_prop(statep, IPADM_OPT_POSSIBLE, buf, bufsize); 6016e91bba0SGirish Moodalbail break; 6026e91bba0SGirish Moodalbail } 6036e91bba0SGirish Moodalbail if (statep->sps_status != IPADM_SUCCESS) 6046e91bba0SGirish Moodalbail cont = _B_FALSE; 6056e91bba0SGirish Moodalbail return (cont); 6066e91bba0SGirish Moodalbail } 6076e91bba0SGirish Moodalbail 6086e91bba0SGirish Moodalbail /* 6096e91bba0SGirish Moodalbail * Callback function called by the property walker (ipadm_walk_prop() or 6106e91bba0SGirish Moodalbail * ipadm_walk_proptbl()), for every matched property. This function in turn 6116e91bba0SGirish Moodalbail * calls ofmt_print() to print property information. 6126e91bba0SGirish Moodalbail */ 6136e91bba0SGirish Moodalbail boolean_t 6146e91bba0SGirish Moodalbail show_property(void *arg, const char *pname, uint_t proto) 6156e91bba0SGirish Moodalbail { 6166e91bba0SGirish Moodalbail show_prop_state_t *statep = arg; 6176e91bba0SGirish Moodalbail 6186e91bba0SGirish Moodalbail statep->sps_pname = pname; 6196e91bba0SGirish Moodalbail statep->sps_proto = proto; 6206e91bba0SGirish Moodalbail statep->sps_status = IPADM_SUCCESS; 6216e91bba0SGirish Moodalbail ofmt_print(statep->sps_ofmt, arg); 6226e91bba0SGirish Moodalbail 6236e91bba0SGirish Moodalbail /* 6246e91bba0SGirish Moodalbail * if an object is not found or operation is not supported then 6256e91bba0SGirish Moodalbail * stop the walker. 6266e91bba0SGirish Moodalbail */ 6276e91bba0SGirish Moodalbail if (statep->sps_status == IPADM_NOTFOUND || 6286e91bba0SGirish Moodalbail statep->sps_status == IPADM_NOTSUP) 6296e91bba0SGirish Moodalbail return (_B_FALSE); 6306e91bba0SGirish Moodalbail return (_B_TRUE); 6316e91bba0SGirish Moodalbail } 6326e91bba0SGirish Moodalbail 6336e91bba0SGirish Moodalbail /* 6346e91bba0SGirish Moodalbail * Properties to be displayed is in `statep->sps_proplist'. If it is NULL, 6356e91bba0SGirish Moodalbail * for all the properties for the specified object, relavant information, will 6366e91bba0SGirish Moodalbail * be displayed. Otherwise, for the selected property set, display relevant 6376e91bba0SGirish Moodalbail * information 6386e91bba0SGirish Moodalbail */ 6396e91bba0SGirish Moodalbail static void 6406e91bba0SGirish Moodalbail show_properties(void *arg, int prop_class) 6416e91bba0SGirish Moodalbail { 6426e91bba0SGirish Moodalbail show_prop_state_t *statep = arg; 6436e91bba0SGirish Moodalbail nvlist_t *nvl = statep->sps_proplist; 6446e91bba0SGirish Moodalbail uint_t proto = statep->sps_proto; 6456e91bba0SGirish Moodalbail nvpair_t *curr_nvp; 6466e91bba0SGirish Moodalbail char *buf, *name; 6476e91bba0SGirish Moodalbail ipadm_status_t status; 6486e91bba0SGirish Moodalbail 6496e91bba0SGirish Moodalbail /* allocate sufficient buffer to hold a property value */ 6506e91bba0SGirish Moodalbail if ((buf = malloc(MAXPROPVALLEN)) == NULL) 6516e91bba0SGirish Moodalbail die("insufficient memory"); 6526e91bba0SGirish Moodalbail statep->sps_propval = buf; 6536e91bba0SGirish Moodalbail 6546e91bba0SGirish Moodalbail /* if no properties were specified, display all the properties */ 6556e91bba0SGirish Moodalbail if (nvl == NULL) { 6566e91bba0SGirish Moodalbail (void) ipadm_walk_proptbl(proto, prop_class, show_property, 6576e91bba0SGirish Moodalbail statep); 6586e91bba0SGirish Moodalbail } else { 6596e91bba0SGirish Moodalbail for (curr_nvp = nvlist_next_nvpair(nvl, NULL); curr_nvp; 6606e91bba0SGirish Moodalbail curr_nvp = nvlist_next_nvpair(nvl, curr_nvp)) { 6616e91bba0SGirish Moodalbail name = nvpair_name(curr_nvp); 6626e91bba0SGirish Moodalbail status = ipadm_walk_prop(name, proto, prop_class, 6636e91bba0SGirish Moodalbail show_property, statep); 6646e91bba0SGirish Moodalbail if (status == IPADM_PROP_UNKNOWN) 6656e91bba0SGirish Moodalbail (void) show_property(statep, name, proto); 6666e91bba0SGirish Moodalbail } 6676e91bba0SGirish Moodalbail } 6686e91bba0SGirish Moodalbail 6696e91bba0SGirish Moodalbail free(buf); 6706e91bba0SGirish Moodalbail } 6716e91bba0SGirish Moodalbail 6726e91bba0SGirish Moodalbail /* 6736e91bba0SGirish Moodalbail * Display information for all or specific interface properties, either for a 6746e91bba0SGirish Moodalbail * given interface or for all the interfaces in the system. 6756e91bba0SGirish Moodalbail */ 6766e91bba0SGirish Moodalbail static void 6776e91bba0SGirish Moodalbail do_show_ifprop(int argc, char **argv, const char *use) 6786e91bba0SGirish Moodalbail { 6796e91bba0SGirish Moodalbail int option; 6806e91bba0SGirish Moodalbail nvlist_t *proplist = NULL; 6816e91bba0SGirish Moodalbail char *fields_str = NULL; 6826e91bba0SGirish Moodalbail char *ifname; 6836e91bba0SGirish Moodalbail ofmt_handle_t ofmt; 6846e91bba0SGirish Moodalbail ofmt_status_t oferr; 6856e91bba0SGirish Moodalbail uint_t ofmtflags = 0; 6866e91bba0SGirish Moodalbail uint_t proto; 6876e91bba0SGirish Moodalbail boolean_t m_arg = _B_FALSE; 6886e91bba0SGirish Moodalbail char *protostr; 6896e91bba0SGirish Moodalbail ipadm_if_info_t *ifinfo, *ifp; 6906e91bba0SGirish Moodalbail ipadm_status_t status; 6916e91bba0SGirish Moodalbail show_prop_state_t state; 6926e91bba0SGirish Moodalbail 6936e91bba0SGirish Moodalbail opterr = 0; 6946e91bba0SGirish Moodalbail bzero(&state, sizeof (state)); 6956e91bba0SGirish Moodalbail state.sps_propval = NULL; 6966e91bba0SGirish Moodalbail state.sps_parsable = _B_FALSE; 6976e91bba0SGirish Moodalbail state.sps_ifprop = _B_TRUE; 6986e91bba0SGirish Moodalbail state.sps_status = state.sps_retstatus = IPADM_SUCCESS; 6996e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":p:m:co:", 7006e91bba0SGirish Moodalbail show_ifprop_longopts, NULL)) != -1) { 7016e91bba0SGirish Moodalbail switch (option) { 7026e91bba0SGirish Moodalbail case 'p': 7036e91bba0SGirish Moodalbail if (ipadm_str2nvlist(optarg, &proplist, 7046e91bba0SGirish Moodalbail IPADM_NORVAL) != 0) 7056e91bba0SGirish Moodalbail die("invalid interface properties specified"); 7066e91bba0SGirish Moodalbail break; 7076e91bba0SGirish Moodalbail case 'c': 7086e91bba0SGirish Moodalbail state.sps_parsable = _B_TRUE; 7096e91bba0SGirish Moodalbail break; 7106e91bba0SGirish Moodalbail case 'o': 7116e91bba0SGirish Moodalbail fields_str = optarg; 7126e91bba0SGirish Moodalbail break; 7136e91bba0SGirish Moodalbail case 'm': 7146e91bba0SGirish Moodalbail if (m_arg) 7156e91bba0SGirish Moodalbail die("cannot specify more than one -m"); 7166e91bba0SGirish Moodalbail m_arg = _B_TRUE; 7176e91bba0SGirish Moodalbail protostr = optarg; 7186e91bba0SGirish Moodalbail break; 7196e91bba0SGirish Moodalbail default: 7206e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 7216e91bba0SGirish Moodalbail break; 7226e91bba0SGirish Moodalbail } 7236e91bba0SGirish Moodalbail } 7246e91bba0SGirish Moodalbail 7256e91bba0SGirish Moodalbail if (optind == argc - 1) 7266e91bba0SGirish Moodalbail ifname = argv[optind]; 7276e91bba0SGirish Moodalbail else if (optind != argc) 7286e91bba0SGirish Moodalbail die("Usage: %s", use); 7296e91bba0SGirish Moodalbail else 7306e91bba0SGirish Moodalbail ifname = NULL; 7316e91bba0SGirish Moodalbail 7326e91bba0SGirish Moodalbail if (!m_arg) 7336e91bba0SGirish Moodalbail protostr = "ip"; 7346e91bba0SGirish Moodalbail if ((proto = ipadm_str2proto(protostr)) == MOD_PROTO_NONE) 7356e91bba0SGirish Moodalbail die("invalid protocol '%s' specified", protostr); 7366e91bba0SGirish Moodalbail 7376e91bba0SGirish Moodalbail state.sps_proto = proto; 7386e91bba0SGirish Moodalbail state.sps_proplist = proplist; 7396e91bba0SGirish Moodalbail 7406e91bba0SGirish Moodalbail if (state.sps_parsable) 7416e91bba0SGirish Moodalbail ofmtflags |= OFMT_PARSABLE; 7426e91bba0SGirish Moodalbail oferr = ofmt_open(fields_str, intfprop_fields, ofmtflags, 0, &ofmt); 7436e91bba0SGirish Moodalbail ipadm_ofmt_check(oferr, state.sps_parsable, ofmt); 7446e91bba0SGirish Moodalbail state.sps_ofmt = ofmt; 7456e91bba0SGirish Moodalbail 7466e91bba0SGirish Moodalbail /* retrieve interface(s) and print the properties */ 7476e91bba0SGirish Moodalbail status = ipadm_if_info(iph, ifname, &ifinfo, 0, LIFC_DEFAULT); 7486e91bba0SGirish Moodalbail if (ifname != NULL && status == IPADM_ENXIO) 7496e91bba0SGirish Moodalbail die("no such object '%s': %s", ifname, 7506e91bba0SGirish Moodalbail ipadm_status2str(status)); 7516e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 7526e91bba0SGirish Moodalbail die("Error retrieving interface(s): %s", 7536e91bba0SGirish Moodalbail ipadm_status2str(status)); 7546e91bba0SGirish Moodalbail for (ifp = ifinfo; ifp; ifp = ifp->ifi_next) { 7556e91bba0SGirish Moodalbail (void) strlcpy(state.sps_ifname, ifp->ifi_name, LIFNAMSIZ); 7566e91bba0SGirish Moodalbail state.sps_proto = proto; 7576e91bba0SGirish Moodalbail show_properties(&state, IPADMPROP_CLASS_IF); 7586e91bba0SGirish Moodalbail } 7596e91bba0SGirish Moodalbail if (ifinfo) 7606e91bba0SGirish Moodalbail ipadm_free_if_info(ifinfo); 7616e91bba0SGirish Moodalbail 7626e91bba0SGirish Moodalbail nvlist_free(proplist); 7636e91bba0SGirish Moodalbail ofmt_close(ofmt); 7646e91bba0SGirish Moodalbail 7656e91bba0SGirish Moodalbail if (state.sps_retstatus != IPADM_SUCCESS) { 7666e91bba0SGirish Moodalbail ipadm_close(iph); 7676e91bba0SGirish Moodalbail exit(EXIT_FAILURE); 7686e91bba0SGirish Moodalbail } 7696e91bba0SGirish Moodalbail } 7706e91bba0SGirish Moodalbail 7716e91bba0SGirish Moodalbail /* 7726e91bba0SGirish Moodalbail * set/reset the interface property for a given interface. 7736e91bba0SGirish Moodalbail */ 7746e91bba0SGirish Moodalbail static void 7756e91bba0SGirish Moodalbail set_ifprop(int argc, char **argv, boolean_t reset, const char *use) 7766e91bba0SGirish Moodalbail { 7776e91bba0SGirish Moodalbail int option; 7786e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 7796e91bba0SGirish Moodalbail boolean_t p_arg = _B_FALSE; 7806e91bba0SGirish Moodalbail boolean_t m_arg = _B_FALSE; 7816e91bba0SGirish Moodalbail char *ifname, *nv, *protostr; 7826e91bba0SGirish Moodalbail char *prop_name, *prop_val; 7836e91bba0SGirish Moodalbail uint_t flags = IPADM_OPT_PERSIST; 7846e91bba0SGirish Moodalbail uint_t proto; 7856e91bba0SGirish Moodalbail 7866e91bba0SGirish Moodalbail opterr = 0; 7876e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":m:p:t", 7886e91bba0SGirish Moodalbail set_ifprop_longopts, NULL)) != -1) { 7896e91bba0SGirish Moodalbail switch (option) { 7906e91bba0SGirish Moodalbail case 'p': 7916e91bba0SGirish Moodalbail if (p_arg) 7926e91bba0SGirish Moodalbail die("-p must be specified once only"); 7936e91bba0SGirish Moodalbail p_arg = _B_TRUE; 7946e91bba0SGirish Moodalbail 7956e91bba0SGirish Moodalbail ipadm_check_propstr(optarg, reset, use); 7966e91bba0SGirish Moodalbail nv = optarg; 7976e91bba0SGirish Moodalbail break; 7986e91bba0SGirish Moodalbail case 'm': 7996e91bba0SGirish Moodalbail if (m_arg) 8006e91bba0SGirish Moodalbail die("-m must be specified once only"); 8016e91bba0SGirish Moodalbail m_arg = _B_TRUE; 8026e91bba0SGirish Moodalbail protostr = optarg; 8036e91bba0SGirish Moodalbail break; 8046e91bba0SGirish Moodalbail case 't': 8056e91bba0SGirish Moodalbail flags &= ~IPADM_OPT_PERSIST; 8066e91bba0SGirish Moodalbail break; 8076e91bba0SGirish Moodalbail default: 8086e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 8096e91bba0SGirish Moodalbail } 8106e91bba0SGirish Moodalbail } 8116e91bba0SGirish Moodalbail 8126e91bba0SGirish Moodalbail if (!m_arg || !p_arg || optind != argc - 1) 8136e91bba0SGirish Moodalbail die("Usage: %s", use); 8146e91bba0SGirish Moodalbail 8156e91bba0SGirish Moodalbail ifname = argv[optind]; 8166e91bba0SGirish Moodalbail 8176e91bba0SGirish Moodalbail prop_name = nv; 8186e91bba0SGirish Moodalbail prop_val = strchr(nv, '='); 8196e91bba0SGirish Moodalbail if (prop_val != NULL) 8206e91bba0SGirish Moodalbail *prop_val++ = '\0'; 8216e91bba0SGirish Moodalbail 8226e91bba0SGirish Moodalbail if ((proto = ipadm_str2proto(protostr)) == MOD_PROTO_NONE) 8236e91bba0SGirish Moodalbail die("invalid protocol '%s' specified", protostr); 8246e91bba0SGirish Moodalbail 8256e91bba0SGirish Moodalbail if (reset) 8266e91bba0SGirish Moodalbail flags |= IPADM_OPT_DEFAULT; 8276e91bba0SGirish Moodalbail else 8286e91bba0SGirish Moodalbail flags |= IPADM_OPT_ACTIVE; 8296e91bba0SGirish Moodalbail status = ipadm_set_ifprop(iph, ifname, prop_name, prop_val, proto, 8306e91bba0SGirish Moodalbail flags); 8316e91bba0SGirish Moodalbail 8326e91bba0SGirish Moodalbail done: 8336e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 8346e91bba0SGirish Moodalbail if (reset) 8356e91bba0SGirish Moodalbail die("reset-ifprop: %s: %s", 8366e91bba0SGirish Moodalbail prop_name, ipadm_status2str(status)); 8376e91bba0SGirish Moodalbail else 8386e91bba0SGirish Moodalbail die("set-ifprop: %s: %s", 8396e91bba0SGirish Moodalbail prop_name, ipadm_status2str(status)); 8406e91bba0SGirish Moodalbail } 8416e91bba0SGirish Moodalbail } 8426e91bba0SGirish Moodalbail 8436e91bba0SGirish Moodalbail static void 8446e91bba0SGirish Moodalbail do_set_ifprop(int argc, char **argv, const char *use) 8456e91bba0SGirish Moodalbail { 8466e91bba0SGirish Moodalbail set_ifprop(argc, argv, _B_FALSE, use); 8476e91bba0SGirish Moodalbail } 8486e91bba0SGirish Moodalbail 8496e91bba0SGirish Moodalbail static void 8506e91bba0SGirish Moodalbail do_reset_ifprop(int argc, char **argv, const char *use) 8516e91bba0SGirish Moodalbail { 8526e91bba0SGirish Moodalbail set_ifprop(argc, argv, _B_TRUE, use); 8536e91bba0SGirish Moodalbail } 8546e91bba0SGirish Moodalbail 8556e91bba0SGirish Moodalbail /* 8566e91bba0SGirish Moodalbail * Display information for all or specific protocol properties, either for a 8576e91bba0SGirish Moodalbail * given protocol or for supported protocols (IP/IPv4/IPv6/TCP/UDP/SCTP) 8586e91bba0SGirish Moodalbail */ 8596e91bba0SGirish Moodalbail static void 8606e91bba0SGirish Moodalbail do_show_prop(int argc, char **argv, const char *use) 8616e91bba0SGirish Moodalbail { 8626e91bba0SGirish Moodalbail char option; 8636e91bba0SGirish Moodalbail nvlist_t *proplist = NULL; 8646e91bba0SGirish Moodalbail char *fields_str = NULL; 8656e91bba0SGirish Moodalbail char *protostr; 8666e91bba0SGirish Moodalbail show_prop_state_t state; 8676e91bba0SGirish Moodalbail ofmt_handle_t ofmt; 8686e91bba0SGirish Moodalbail ofmt_status_t oferr; 8696e91bba0SGirish Moodalbail uint_t ofmtflags = 0; 8706e91bba0SGirish Moodalbail uint_t proto; 8716e91bba0SGirish Moodalbail boolean_t p_arg = _B_FALSE; 8726e91bba0SGirish Moodalbail 8736e91bba0SGirish Moodalbail opterr = 0; 8746e91bba0SGirish Moodalbail bzero(&state, sizeof (state)); 8756e91bba0SGirish Moodalbail state.sps_propval = NULL; 8766e91bba0SGirish Moodalbail state.sps_parsable = _B_FALSE; 8776e91bba0SGirish Moodalbail state.sps_modprop = _B_TRUE; 8786e91bba0SGirish Moodalbail state.sps_status = state.sps_retstatus = IPADM_SUCCESS; 8796e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":p:co:", show_prop_longopts, 8806e91bba0SGirish Moodalbail NULL)) != -1) { 8816e91bba0SGirish Moodalbail switch (option) { 8826e91bba0SGirish Moodalbail case 'p': 8836e91bba0SGirish Moodalbail if (p_arg) 8846e91bba0SGirish Moodalbail die("-p must be specified once only"); 8856e91bba0SGirish Moodalbail p_arg = _B_TRUE; 8866e91bba0SGirish Moodalbail if (ipadm_str2nvlist(optarg, &proplist, 8876e91bba0SGirish Moodalbail IPADM_NORVAL) != 0) 8886e91bba0SGirish Moodalbail die("invalid protocol properties specified"); 8896e91bba0SGirish Moodalbail break; 8906e91bba0SGirish Moodalbail case 'c': 8916e91bba0SGirish Moodalbail state.sps_parsable = _B_TRUE; 8926e91bba0SGirish Moodalbail break; 8936e91bba0SGirish Moodalbail case 'o': 8946e91bba0SGirish Moodalbail fields_str = optarg; 8956e91bba0SGirish Moodalbail break; 8966e91bba0SGirish Moodalbail default: 8976e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 8986e91bba0SGirish Moodalbail break; 8996e91bba0SGirish Moodalbail } 9006e91bba0SGirish Moodalbail } 9016e91bba0SGirish Moodalbail if (optind == argc - 1) { 9026e91bba0SGirish Moodalbail protostr = argv[optind]; 9036e91bba0SGirish Moodalbail if ((proto = ipadm_str2proto(protostr)) == MOD_PROTO_NONE) 9046e91bba0SGirish Moodalbail die("invalid protocol '%s' specified", protostr); 9056e91bba0SGirish Moodalbail state.sps_proto = proto; 9066e91bba0SGirish Moodalbail } else if (optind != argc) { 9076e91bba0SGirish Moodalbail die("Usage: %s", use); 9086e91bba0SGirish Moodalbail } else { 9096e91bba0SGirish Moodalbail if (p_arg) 9106e91bba0SGirish Moodalbail die("protocol must be specified when " 9116e91bba0SGirish Moodalbail "property name is used"); 9126e91bba0SGirish Moodalbail state.sps_proto = MOD_PROTO_NONE; 9136e91bba0SGirish Moodalbail } 9146e91bba0SGirish Moodalbail 9156e91bba0SGirish Moodalbail state.sps_proplist = proplist; 9166e91bba0SGirish Moodalbail 9176e91bba0SGirish Moodalbail if (state.sps_parsable) 9186e91bba0SGirish Moodalbail ofmtflags |= OFMT_PARSABLE; 9196e91bba0SGirish Moodalbail else 9206e91bba0SGirish Moodalbail ofmtflags |= OFMT_WRAP; 9216e91bba0SGirish Moodalbail oferr = ofmt_open(fields_str, modprop_fields, ofmtflags, 0, &ofmt); 9226e91bba0SGirish Moodalbail ipadm_ofmt_check(oferr, state.sps_parsable, ofmt); 9236e91bba0SGirish Moodalbail state.sps_ofmt = ofmt; 9246e91bba0SGirish Moodalbail 9256e91bba0SGirish Moodalbail /* handles all the errors */ 9266e91bba0SGirish Moodalbail show_properties(&state, IPADMPROP_CLASS_MODULE); 9276e91bba0SGirish Moodalbail 9286e91bba0SGirish Moodalbail nvlist_free(proplist); 9296e91bba0SGirish Moodalbail ofmt_close(ofmt); 9306e91bba0SGirish Moodalbail 9316e91bba0SGirish Moodalbail if (state.sps_retstatus != IPADM_SUCCESS) { 9326e91bba0SGirish Moodalbail ipadm_close(iph); 9336e91bba0SGirish Moodalbail exit(EXIT_FAILURE); 9346e91bba0SGirish Moodalbail } 9356e91bba0SGirish Moodalbail } 9366e91bba0SGirish Moodalbail 9376e91bba0SGirish Moodalbail /* 9386e91bba0SGirish Moodalbail * Checks to see if there are any modifiers, + or -. If there are modifiers 9396e91bba0SGirish Moodalbail * then sets IPADM_OPT_APPEND or IPADM_OPT_REMOVE, accordingly. 9406e91bba0SGirish Moodalbail */ 9416e91bba0SGirish Moodalbail static void 9428b88711aSGirish Moodalbail parse_modifiers(const char *pstr, uint_t *flags, const char *use) 9436e91bba0SGirish Moodalbail { 9446e91bba0SGirish Moodalbail char *p; 9456e91bba0SGirish Moodalbail 9468b88711aSGirish Moodalbail if ((p = strchr(pstr, '=')) == NULL) 9478b88711aSGirish Moodalbail return; 9486e91bba0SGirish Moodalbail 9498b88711aSGirish Moodalbail if (p == pstr) 9508b88711aSGirish Moodalbail die("Invalid prop=val specified\n%s", use); 9516e91bba0SGirish Moodalbail 9528b88711aSGirish Moodalbail --p; 9538b88711aSGirish Moodalbail if (*p == '+') 9546e91bba0SGirish Moodalbail *flags |= IPADM_OPT_APPEND; 9558b88711aSGirish Moodalbail else if (*p == '-') 9566e91bba0SGirish Moodalbail *flags |= IPADM_OPT_REMOVE; 9576e91bba0SGirish Moodalbail } 9586e91bba0SGirish Moodalbail 9596e91bba0SGirish Moodalbail /* 9606e91bba0SGirish Moodalbail * set/reset the protocol property for a given protocol. 9616e91bba0SGirish Moodalbail */ 9626e91bba0SGirish Moodalbail static void 9636e91bba0SGirish Moodalbail set_prop(int argc, char **argv, boolean_t reset, const char *use) 9646e91bba0SGirish Moodalbail { 9656e91bba0SGirish Moodalbail int option; 9666e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 9676e91bba0SGirish Moodalbail char *protostr, *nv, *prop_name, *prop_val; 9686e91bba0SGirish Moodalbail boolean_t p_arg = _B_FALSE; 9696e91bba0SGirish Moodalbail uint_t proto; 9706e91bba0SGirish Moodalbail uint_t flags = IPADM_OPT_PERSIST; 9716e91bba0SGirish Moodalbail 9726e91bba0SGirish Moodalbail opterr = 0; 9736e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":p:t", set_prop_longopts, 9746e91bba0SGirish Moodalbail NULL)) != -1) { 9756e91bba0SGirish Moodalbail switch (option) { 9766e91bba0SGirish Moodalbail case 'p': 9776e91bba0SGirish Moodalbail if (p_arg) 9786e91bba0SGirish Moodalbail die("-p must be specified once only"); 9796e91bba0SGirish Moodalbail p_arg = _B_TRUE; 9806e91bba0SGirish Moodalbail 9816e91bba0SGirish Moodalbail ipadm_check_propstr(optarg, reset, use); 9826e91bba0SGirish Moodalbail nv = optarg; 9836e91bba0SGirish Moodalbail break; 9846e91bba0SGirish Moodalbail case 't': 9856e91bba0SGirish Moodalbail flags &= ~IPADM_OPT_PERSIST; 9866e91bba0SGirish Moodalbail break; 9876e91bba0SGirish Moodalbail default: 9886e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 9896e91bba0SGirish Moodalbail } 9906e91bba0SGirish Moodalbail } 9916e91bba0SGirish Moodalbail 9926e91bba0SGirish Moodalbail if (!p_arg || optind != argc - 1) 9936e91bba0SGirish Moodalbail die("Usage: %s", use); 9946e91bba0SGirish Moodalbail 9956e91bba0SGirish Moodalbail parse_modifiers(nv, &flags, use); 9966e91bba0SGirish Moodalbail prop_name = nv; 9976e91bba0SGirish Moodalbail prop_val = strchr(nv, '='); 9986e91bba0SGirish Moodalbail if (prop_val != NULL) { 9996e91bba0SGirish Moodalbail if (flags & (IPADM_OPT_APPEND|IPADM_OPT_REMOVE)) 10006e91bba0SGirish Moodalbail *(prop_val - 1) = '\0'; 10016e91bba0SGirish Moodalbail *prop_val++ = '\0'; 10026e91bba0SGirish Moodalbail } 10036e91bba0SGirish Moodalbail protostr = argv[optind]; 10046e91bba0SGirish Moodalbail if ((proto = ipadm_str2proto(protostr)) == MOD_PROTO_NONE) 10056e91bba0SGirish Moodalbail die("invalid protocol '%s' specified", protostr); 10066e91bba0SGirish Moodalbail 10076e91bba0SGirish Moodalbail if (reset) 10086e91bba0SGirish Moodalbail flags |= IPADM_OPT_DEFAULT; 10096e91bba0SGirish Moodalbail else 10106e91bba0SGirish Moodalbail flags |= IPADM_OPT_ACTIVE; 10116e91bba0SGirish Moodalbail status = ipadm_set_prop(iph, prop_name, prop_val, proto, flags); 10126e91bba0SGirish Moodalbail done: 10136e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 10146e91bba0SGirish Moodalbail if (reset) 10156e91bba0SGirish Moodalbail die("reset-prop: %s: %s", 10166e91bba0SGirish Moodalbail prop_name, ipadm_status2str(status)); 10176e91bba0SGirish Moodalbail else 10186e91bba0SGirish Moodalbail die("set-prop: %s: %s", 10196e91bba0SGirish Moodalbail prop_name, ipadm_status2str(status)); 10206e91bba0SGirish Moodalbail } 10216e91bba0SGirish Moodalbail } 10226e91bba0SGirish Moodalbail 10236e91bba0SGirish Moodalbail static void 10246e91bba0SGirish Moodalbail do_set_prop(int argc, char **argv, const char *use) 10256e91bba0SGirish Moodalbail { 10266e91bba0SGirish Moodalbail set_prop(argc, argv, _B_FALSE, use); 10276e91bba0SGirish Moodalbail } 10286e91bba0SGirish Moodalbail 10296e91bba0SGirish Moodalbail static void 10306e91bba0SGirish Moodalbail do_reset_prop(int argc, char **argv, const char *use) 10316e91bba0SGirish Moodalbail { 10326e91bba0SGirish Moodalbail set_prop(argc, argv, _B_TRUE, use); 10336e91bba0SGirish Moodalbail } 10346e91bba0SGirish Moodalbail 10356e91bba0SGirish Moodalbail /* PRINTFLIKE1 */ 10366e91bba0SGirish Moodalbail static void 10376e91bba0SGirish Moodalbail warn(const char *format, ...) 10386e91bba0SGirish Moodalbail { 10396e91bba0SGirish Moodalbail va_list alist; 10406e91bba0SGirish Moodalbail 10416e91bba0SGirish Moodalbail format = gettext(format); 10426e91bba0SGirish Moodalbail (void) fprintf(stderr, gettext("%s: warning: "), progname); 10436e91bba0SGirish Moodalbail 10446e91bba0SGirish Moodalbail va_start(alist, format); 10456e91bba0SGirish Moodalbail (void) vfprintf(stderr, format, alist); 10466e91bba0SGirish Moodalbail va_end(alist); 10476e91bba0SGirish Moodalbail 10486e91bba0SGirish Moodalbail (void) fprintf(stderr, "\n"); 10496e91bba0SGirish Moodalbail } 10506e91bba0SGirish Moodalbail 10516e91bba0SGirish Moodalbail /* PRINTFLIKE1 */ 10526e91bba0SGirish Moodalbail static void 10536e91bba0SGirish Moodalbail die(const char *format, ...) 10546e91bba0SGirish Moodalbail { 10556e91bba0SGirish Moodalbail va_list alist; 10566e91bba0SGirish Moodalbail 10576e91bba0SGirish Moodalbail format = gettext(format); 10586e91bba0SGirish Moodalbail (void) fprintf(stderr, "%s: ", progname); 10596e91bba0SGirish Moodalbail 10606e91bba0SGirish Moodalbail va_start(alist, format); 10616e91bba0SGirish Moodalbail (void) vfprintf(stderr, format, alist); 10626e91bba0SGirish Moodalbail va_end(alist); 10636e91bba0SGirish Moodalbail 10646e91bba0SGirish Moodalbail (void) putchar('\n'); 10656e91bba0SGirish Moodalbail 10666e91bba0SGirish Moodalbail ipadm_destroy_addrobj(ipaddr); 10676e91bba0SGirish Moodalbail ipadm_close(iph); 10686e91bba0SGirish Moodalbail exit(EXIT_FAILURE); 10696e91bba0SGirish Moodalbail } 10706e91bba0SGirish Moodalbail 10716e91bba0SGirish Moodalbail static void 10726e91bba0SGirish Moodalbail die_opterr(int opt, int opterr, const char *usage) 10736e91bba0SGirish Moodalbail { 10746e91bba0SGirish Moodalbail switch (opterr) { 10756e91bba0SGirish Moodalbail case ':': 10766e91bba0SGirish Moodalbail die("option '-%c' requires a value\nusage: %s", opt, 10776e91bba0SGirish Moodalbail gettext(usage)); 10786e91bba0SGirish Moodalbail break; 10796e91bba0SGirish Moodalbail case '?': 10806e91bba0SGirish Moodalbail default: 10816e91bba0SGirish Moodalbail die("unrecognized option '-%c'\nusage: %s", opt, 10826e91bba0SGirish Moodalbail gettext(usage)); 10836e91bba0SGirish Moodalbail break; 10846e91bba0SGirish Moodalbail } 10856e91bba0SGirish Moodalbail } 10866e91bba0SGirish Moodalbail 10876e91bba0SGirish Moodalbail /* PRINTFLIKE2 */ 10886e91bba0SGirish Moodalbail static void 10896e91bba0SGirish Moodalbail warn_ipadmerr(ipadm_status_t err, const char *format, ...) 10906e91bba0SGirish Moodalbail { 10916e91bba0SGirish Moodalbail va_list alist; 10926e91bba0SGirish Moodalbail 10936e91bba0SGirish Moodalbail format = gettext(format); 10946e91bba0SGirish Moodalbail (void) fprintf(stderr, gettext("%s: warning: "), progname); 10956e91bba0SGirish Moodalbail 10966e91bba0SGirish Moodalbail va_start(alist, format); 10976e91bba0SGirish Moodalbail (void) vfprintf(stderr, format, alist); 10986e91bba0SGirish Moodalbail va_end(alist); 10996e91bba0SGirish Moodalbail 11006e91bba0SGirish Moodalbail (void) fprintf(stderr, "%s\n", ipadm_status2str(err)); 11016e91bba0SGirish Moodalbail } 11026e91bba0SGirish Moodalbail 11036e91bba0SGirish Moodalbail static void 11046e91bba0SGirish Moodalbail process_static_addrargs(const char *use, char *addrarg, const char *aobjname) 11056e91bba0SGirish Moodalbail { 11066e91bba0SGirish Moodalbail int option; 11076e91bba0SGirish Moodalbail char *val; 11086e91bba0SGirish Moodalbail char *laddr = NULL; 11096e91bba0SGirish Moodalbail char *raddr = NULL; 11106e91bba0SGirish Moodalbail char *save_input_arg = addrarg; 11116e91bba0SGirish Moodalbail boolean_t found_mismatch = _B_FALSE; 11126e91bba0SGirish Moodalbail ipadm_status_t status; 11136e91bba0SGirish Moodalbail enum { A_LOCAL, A_REMOTE }; 11146e91bba0SGirish Moodalbail static char *addr_optstr[] = { 11156e91bba0SGirish Moodalbail "local", 11166e91bba0SGirish Moodalbail "remote", 11176e91bba0SGirish Moodalbail NULL, 11186e91bba0SGirish Moodalbail }; 11196e91bba0SGirish Moodalbail 11206e91bba0SGirish Moodalbail while (*addrarg != '\0') { 11216e91bba0SGirish Moodalbail option = getsubopt(&addrarg, addr_optstr, &val); 11226e91bba0SGirish Moodalbail switch (option) { 11236e91bba0SGirish Moodalbail case A_LOCAL: 11246e91bba0SGirish Moodalbail if (laddr != NULL) 11256e91bba0SGirish Moodalbail die("Multiple local addresses provided"); 11266e91bba0SGirish Moodalbail laddr = val; 11276e91bba0SGirish Moodalbail break; 11286e91bba0SGirish Moodalbail case A_REMOTE: 11296e91bba0SGirish Moodalbail if (raddr != NULL) 11306e91bba0SGirish Moodalbail die("Multiple remote addresses provided"); 11316e91bba0SGirish Moodalbail raddr = val; 11326e91bba0SGirish Moodalbail break; 11336e91bba0SGirish Moodalbail default: 11346e91bba0SGirish Moodalbail if (found_mismatch) 11356e91bba0SGirish Moodalbail die("Invalid address provided\nusage: %s", use); 11366e91bba0SGirish Moodalbail found_mismatch = _B_TRUE; 11376e91bba0SGirish Moodalbail break; 11386e91bba0SGirish Moodalbail } 11396e91bba0SGirish Moodalbail } 11406e91bba0SGirish Moodalbail if (raddr != NULL && laddr == NULL) 11416e91bba0SGirish Moodalbail die("Missing local address\nusage: %s", use); 11426e91bba0SGirish Moodalbail 11436e91bba0SGirish Moodalbail /* If only one address is provided, it is assumed a local address. */ 11446e91bba0SGirish Moodalbail if (laddr == NULL) { 11456e91bba0SGirish Moodalbail if (found_mismatch) 11466e91bba0SGirish Moodalbail laddr = save_input_arg; 11476e91bba0SGirish Moodalbail else 11486e91bba0SGirish Moodalbail die("Missing local address\nusage: %s", use); 11496e91bba0SGirish Moodalbail } 11506e91bba0SGirish Moodalbail 11516e91bba0SGirish Moodalbail /* Initialize the addrobj for static addresses. */ 11526e91bba0SGirish Moodalbail status = ipadm_create_addrobj(IPADM_ADDR_STATIC, aobjname, &ipaddr); 11536e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 11546e91bba0SGirish Moodalbail die("Error in creating address object: %s", 11556e91bba0SGirish Moodalbail ipadm_status2str(status)); 11566e91bba0SGirish Moodalbail } 11576e91bba0SGirish Moodalbail 11586e91bba0SGirish Moodalbail /* Set the local and remote addresses */ 11596e91bba0SGirish Moodalbail status = ipadm_set_addr(ipaddr, laddr, AF_UNSPEC); 11606e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 11616e91bba0SGirish Moodalbail die("Error in setting local address: %s", 11626e91bba0SGirish Moodalbail ipadm_status2str(status)); 11636e91bba0SGirish Moodalbail } 11646e91bba0SGirish Moodalbail if (raddr != NULL) { 11656e91bba0SGirish Moodalbail status = ipadm_set_dst_addr(ipaddr, raddr, AF_UNSPEC); 11666e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 11676e91bba0SGirish Moodalbail die("Error in setting remote address: %s", 11686e91bba0SGirish Moodalbail ipadm_status2str(status)); 11696e91bba0SGirish Moodalbail } 11706e91bba0SGirish Moodalbail } 11716e91bba0SGirish Moodalbail } 11726e91bba0SGirish Moodalbail 11736e91bba0SGirish Moodalbail static void 11746e91bba0SGirish Moodalbail process_addrconf_addrargs(const char *use, char *addrarg) 11756e91bba0SGirish Moodalbail { 11766e91bba0SGirish Moodalbail int option; 11776e91bba0SGirish Moodalbail char *val; 11786e91bba0SGirish Moodalbail enum { P_STATELESS, P_STATEFUL }; 11796e91bba0SGirish Moodalbail static char *addr_optstr[] = { 11806e91bba0SGirish Moodalbail "stateless", 11816e91bba0SGirish Moodalbail "stateful", 11826e91bba0SGirish Moodalbail NULL, 11836e91bba0SGirish Moodalbail }; 11846e91bba0SGirish Moodalbail boolean_t stateless; 11856e91bba0SGirish Moodalbail boolean_t stateless_arg = _B_FALSE; 11866e91bba0SGirish Moodalbail boolean_t stateful; 11876e91bba0SGirish Moodalbail boolean_t stateful_arg = _B_FALSE; 11886e91bba0SGirish Moodalbail ipadm_status_t status; 11896e91bba0SGirish Moodalbail 11906e91bba0SGirish Moodalbail while (*addrarg != '\0') { 11916e91bba0SGirish Moodalbail option = getsubopt(&addrarg, addr_optstr, &val); 11926e91bba0SGirish Moodalbail switch (option) { 11936e91bba0SGirish Moodalbail case P_STATELESS: 11946e91bba0SGirish Moodalbail if (stateless_arg) 11956e91bba0SGirish Moodalbail die("Duplicate option"); 1196*7bc87895SYuri Pankov if (val == NULL) 1197*7bc87895SYuri Pankov die("Invalid argument"); 11986e91bba0SGirish Moodalbail if (strcmp(val, "yes") == 0) 11996e91bba0SGirish Moodalbail stateless = _B_TRUE; 12006e91bba0SGirish Moodalbail else if (strcmp(val, "no") == 0) 12016e91bba0SGirish Moodalbail stateless = _B_FALSE; 12026e91bba0SGirish Moodalbail else 12036e91bba0SGirish Moodalbail die("Invalid argument"); 12046e91bba0SGirish Moodalbail stateless_arg = _B_TRUE; 12056e91bba0SGirish Moodalbail break; 12066e91bba0SGirish Moodalbail case P_STATEFUL: 12076e91bba0SGirish Moodalbail if (stateful_arg) 12086e91bba0SGirish Moodalbail die("Duplicate option"); 1209*7bc87895SYuri Pankov if (val == NULL) 1210*7bc87895SYuri Pankov die("Invalid argument"); 12116e91bba0SGirish Moodalbail if (strcmp(val, "yes") == 0) 12126e91bba0SGirish Moodalbail stateful = _B_TRUE; 12136e91bba0SGirish Moodalbail else if (strcmp(val, "no") == 0) 12146e91bba0SGirish Moodalbail stateful = _B_FALSE; 12156e91bba0SGirish Moodalbail else 12166e91bba0SGirish Moodalbail die("Invalid argument"); 12176e91bba0SGirish Moodalbail stateful_arg = _B_TRUE; 12186e91bba0SGirish Moodalbail break; 12196e91bba0SGirish Moodalbail default: 12206e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 12216e91bba0SGirish Moodalbail } 12226e91bba0SGirish Moodalbail } 12236e91bba0SGirish Moodalbail 12246e91bba0SGirish Moodalbail if (!stateless_arg && !stateful_arg) 12256e91bba0SGirish Moodalbail die("Invalid arguments for option -p"); 12266e91bba0SGirish Moodalbail 12276e91bba0SGirish Moodalbail /* Set the addrobj fields for addrconf */ 12286e91bba0SGirish Moodalbail if (stateless_arg) { 12296e91bba0SGirish Moodalbail status = ipadm_set_stateless(ipaddr, stateless); 12306e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 12316e91bba0SGirish Moodalbail die("Error in setting stateless option: %s", 12326e91bba0SGirish Moodalbail ipadm_status2str(status)); 12336e91bba0SGirish Moodalbail } 12346e91bba0SGirish Moodalbail } 12356e91bba0SGirish Moodalbail if (stateful_arg) { 12366e91bba0SGirish Moodalbail status = ipadm_set_stateful(ipaddr, stateful); 12376e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 12386e91bba0SGirish Moodalbail die("Error in setting stateful option: %s", 12396e91bba0SGirish Moodalbail ipadm_status2str(status)); 12406e91bba0SGirish Moodalbail } 12416e91bba0SGirish Moodalbail } 12426e91bba0SGirish Moodalbail } 12436e91bba0SGirish Moodalbail 12446e91bba0SGirish Moodalbail /* 12456e91bba0SGirish Moodalbail * Creates static, dhcp or addrconf addresses and associates the created 12466e91bba0SGirish Moodalbail * addresses with the specified address object name. 12476e91bba0SGirish Moodalbail */ 12486e91bba0SGirish Moodalbail static void 12496e91bba0SGirish Moodalbail do_create_addr(int argc, char *argv[], const char *use) 12506e91bba0SGirish Moodalbail { 12516e91bba0SGirish Moodalbail ipadm_status_t status; 12526e91bba0SGirish Moodalbail int option; 12536e91bba0SGirish Moodalbail uint32_t flags = 1254f6da83d4SAnurag S. Maskey IPADM_OPT_PERSIST|IPADM_OPT_ACTIVE|IPADM_OPT_UP|IPADM_OPT_V46; 12556e91bba0SGirish Moodalbail char *cp; 12566e91bba0SGirish Moodalbail char *atype = NULL; 12576e91bba0SGirish Moodalbail char *static_arg = NULL; 12586e91bba0SGirish Moodalbail char *addrconf_arg = NULL; 12596e91bba0SGirish Moodalbail char *interface_id = NULL; 12606e91bba0SGirish Moodalbail char *wait = NULL; 12616e91bba0SGirish Moodalbail boolean_t s_opt = _B_FALSE; /* static addr options */ 12626e91bba0SGirish Moodalbail boolean_t auto_opt = _B_FALSE; /* Addrconf options */ 12636e91bba0SGirish Moodalbail boolean_t dhcp_opt = _B_FALSE; /* dhcp options */ 12646e91bba0SGirish Moodalbail 12656e91bba0SGirish Moodalbail opterr = 0; 12666e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":T:a:di:p:w:t", 12676e91bba0SGirish Moodalbail addr_longopts, NULL)) != -1) { 12686e91bba0SGirish Moodalbail switch (option) { 12696e91bba0SGirish Moodalbail case 'T': 12706e91bba0SGirish Moodalbail atype = optarg; 12716e91bba0SGirish Moodalbail break; 12726e91bba0SGirish Moodalbail case 'a': 12736e91bba0SGirish Moodalbail static_arg = optarg; 12746e91bba0SGirish Moodalbail s_opt = _B_TRUE; 12756e91bba0SGirish Moodalbail break; 12766e91bba0SGirish Moodalbail case 'd': 12776e91bba0SGirish Moodalbail flags &= ~IPADM_OPT_UP; 12786e91bba0SGirish Moodalbail s_opt = _B_TRUE; 12796e91bba0SGirish Moodalbail break; 12806e91bba0SGirish Moodalbail case 'i': 12816e91bba0SGirish Moodalbail interface_id = optarg; 12826e91bba0SGirish Moodalbail auto_opt = _B_TRUE; 12836e91bba0SGirish Moodalbail break; 12846e91bba0SGirish Moodalbail case 'p': 12856e91bba0SGirish Moodalbail addrconf_arg = optarg; 12866e91bba0SGirish Moodalbail auto_opt = _B_TRUE; 12876e91bba0SGirish Moodalbail break; 12886e91bba0SGirish Moodalbail case 'w': 12896e91bba0SGirish Moodalbail wait = optarg; 12906e91bba0SGirish Moodalbail dhcp_opt = _B_TRUE; 12916e91bba0SGirish Moodalbail break; 12926e91bba0SGirish Moodalbail case 't': 12936e91bba0SGirish Moodalbail flags &= ~IPADM_OPT_PERSIST; 12946e91bba0SGirish Moodalbail break; 12956e91bba0SGirish Moodalbail default: 12966e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 12976e91bba0SGirish Moodalbail } 12986e91bba0SGirish Moodalbail } 12996e91bba0SGirish Moodalbail if (atype == NULL || optind != (argc - 1)) { 13006e91bba0SGirish Moodalbail die("Invalid arguments\nusage: %s", use); 13016e91bba0SGirish Moodalbail } else if ((cp = strchr(argv[optind], '/')) == NULL || 13026e91bba0SGirish Moodalbail strlen(++cp) == 0) { 13036e91bba0SGirish Moodalbail die("invalid address object name: %s\nusage: %s", 13046e91bba0SGirish Moodalbail argv[optind], use); 13056e91bba0SGirish Moodalbail } 13066e91bba0SGirish Moodalbail 13076e91bba0SGirish Moodalbail /* 13086e91bba0SGirish Moodalbail * Allocate and initialize the addrobj based on the address type. 13096e91bba0SGirish Moodalbail */ 13106e91bba0SGirish Moodalbail if (strcmp(atype, "static") == 0) { 13116e91bba0SGirish Moodalbail if (static_arg == NULL || auto_opt || dhcp_opt) { 13126e91bba0SGirish Moodalbail die("Invalid arguments for type %s\nusage: %s", 13136e91bba0SGirish Moodalbail atype, use); 13146e91bba0SGirish Moodalbail } 13156e91bba0SGirish Moodalbail process_static_addrargs(use, static_arg, argv[optind]); 13166e91bba0SGirish Moodalbail } else if (strcmp(atype, "dhcp") == 0) { 13176e91bba0SGirish Moodalbail if (auto_opt || s_opt) { 13186e91bba0SGirish Moodalbail die("Invalid arguments for type %s\nusage: %s", 13196e91bba0SGirish Moodalbail atype, use); 13206e91bba0SGirish Moodalbail } 13216e91bba0SGirish Moodalbail 13226e91bba0SGirish Moodalbail /* Initialize the addrobj for dhcp addresses. */ 13236e91bba0SGirish Moodalbail status = ipadm_create_addrobj(IPADM_ADDR_DHCP, argv[optind], 13246e91bba0SGirish Moodalbail &ipaddr); 13256e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 13266e91bba0SGirish Moodalbail die("Error in creating address object: %s", 13276e91bba0SGirish Moodalbail ipadm_status2str(status)); 13286e91bba0SGirish Moodalbail } 13296e91bba0SGirish Moodalbail if (wait != NULL) { 13306e91bba0SGirish Moodalbail int32_t ipadm_wait; 13316e91bba0SGirish Moodalbail 13326e91bba0SGirish Moodalbail if (strcmp(wait, "forever") == 0) { 13336e91bba0SGirish Moodalbail ipadm_wait = IPADM_DHCP_WAIT_FOREVER; 13346e91bba0SGirish Moodalbail } else { 13356e91bba0SGirish Moodalbail char *end; 13366e91bba0SGirish Moodalbail long timeout = strtol(wait, &end, 10); 13376e91bba0SGirish Moodalbail 13386e91bba0SGirish Moodalbail if (*end != '\0' || timeout < 0) 13396e91bba0SGirish Moodalbail die("Invalid argument"); 13406e91bba0SGirish Moodalbail ipadm_wait = (int32_t)timeout; 13416e91bba0SGirish Moodalbail } 13426e91bba0SGirish Moodalbail status = ipadm_set_wait_time(ipaddr, ipadm_wait); 13436e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 13446e91bba0SGirish Moodalbail die("Error in setting wait time: %s", 13456e91bba0SGirish Moodalbail ipadm_status2str(status)); 13466e91bba0SGirish Moodalbail } 13476e91bba0SGirish Moodalbail } 13486e91bba0SGirish Moodalbail } else if (strcmp(atype, "addrconf") == 0) { 13496e91bba0SGirish Moodalbail if (dhcp_opt || s_opt) { 13506e91bba0SGirish Moodalbail die("Invalid arguments for type %s\nusage: %s", 13516e91bba0SGirish Moodalbail atype, use); 13526e91bba0SGirish Moodalbail } 13536e91bba0SGirish Moodalbail 13546e91bba0SGirish Moodalbail /* Initialize the addrobj for dhcp addresses. */ 13556e91bba0SGirish Moodalbail status = ipadm_create_addrobj(IPADM_ADDR_IPV6_ADDRCONF, 13566e91bba0SGirish Moodalbail argv[optind], &ipaddr); 13576e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 13586e91bba0SGirish Moodalbail die("Error in creating address object: %s", 13596e91bba0SGirish Moodalbail ipadm_status2str(status)); 13606e91bba0SGirish Moodalbail } 13616e91bba0SGirish Moodalbail if (interface_id != NULL) { 13626e91bba0SGirish Moodalbail status = ipadm_set_interface_id(ipaddr, interface_id); 13636e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 13646e91bba0SGirish Moodalbail die("Error in setting interface ID: %s", 13656e91bba0SGirish Moodalbail ipadm_status2str(status)); 13666e91bba0SGirish Moodalbail } 13676e91bba0SGirish Moodalbail } 13686e91bba0SGirish Moodalbail if (addrconf_arg) 13696e91bba0SGirish Moodalbail process_addrconf_addrargs(use, addrconf_arg); 13706e91bba0SGirish Moodalbail } else { 13716e91bba0SGirish Moodalbail die("Invalid address type %s", atype); 13726e91bba0SGirish Moodalbail } 13736e91bba0SGirish Moodalbail 13746e91bba0SGirish Moodalbail status = ipadm_create_addr(iph, ipaddr, flags); 13756e91bba0SGirish Moodalbail if (status == IPADM_DHCP_IPC_TIMEOUT) 13766e91bba0SGirish Moodalbail warn_ipadmerr(status, ""); 13776e91bba0SGirish Moodalbail else if (status != IPADM_SUCCESS) 13786e91bba0SGirish Moodalbail die("Could not create address: %s", ipadm_status2str(status)); 13796e91bba0SGirish Moodalbail } 13806e91bba0SGirish Moodalbail 13816e91bba0SGirish Moodalbail /* 13826e91bba0SGirish Moodalbail * Used by some address management functions to parse the command line 13836e91bba0SGirish Moodalbail * arguments and create `ipaddr' address object. 13846e91bba0SGirish Moodalbail */ 13856e91bba0SGirish Moodalbail static void 13866e91bba0SGirish Moodalbail process_misc_addrargs(int argc, char *argv[], const char *use, int *index, 13876e91bba0SGirish Moodalbail uint32_t *flags) 13886e91bba0SGirish Moodalbail { 13896e91bba0SGirish Moodalbail int option; 13906e91bba0SGirish Moodalbail 13916e91bba0SGirish Moodalbail opterr = 0; 13926e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":t", addr_misc_longopts, 13936e91bba0SGirish Moodalbail NULL)) != -1) { 13946e91bba0SGirish Moodalbail switch (option) { 13956e91bba0SGirish Moodalbail case 't': 13966e91bba0SGirish Moodalbail *flags &= ~IPADM_OPT_PERSIST; 13976e91bba0SGirish Moodalbail break; 13986e91bba0SGirish Moodalbail default: 13996e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 14006e91bba0SGirish Moodalbail } 14016e91bba0SGirish Moodalbail } 14026e91bba0SGirish Moodalbail if (optind != (argc - 1)) 14036e91bba0SGirish Moodalbail die("Usage: %s", use); 14046e91bba0SGirish Moodalbail 14056e91bba0SGirish Moodalbail *index = optind; 14066e91bba0SGirish Moodalbail } 14076e91bba0SGirish Moodalbail 14086e91bba0SGirish Moodalbail /* 14096e91bba0SGirish Moodalbail * Remove an addrobj from both active and persistent configuration. 14106e91bba0SGirish Moodalbail */ 14116e91bba0SGirish Moodalbail static void 14126e91bba0SGirish Moodalbail do_delete_addr(int argc, char *argv[], const char *use) 14136e91bba0SGirish Moodalbail { 14146e91bba0SGirish Moodalbail ipadm_status_t status; 14156e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 14166e91bba0SGirish Moodalbail int option; 14176e91bba0SGirish Moodalbail 14186e91bba0SGirish Moodalbail opterr = 0; 14196e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":r", addr_misc_longopts, 14206e91bba0SGirish Moodalbail NULL)) != -1) { 14216e91bba0SGirish Moodalbail switch (option) { 14226e91bba0SGirish Moodalbail case 'r': 14236e91bba0SGirish Moodalbail flags |= IPADM_OPT_RELEASE; 14246e91bba0SGirish Moodalbail break; 14256e91bba0SGirish Moodalbail default: 14266e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 14276e91bba0SGirish Moodalbail } 14286e91bba0SGirish Moodalbail } 14296e91bba0SGirish Moodalbail if (optind != (argc - 1)) 14306e91bba0SGirish Moodalbail die("Usage: %s", use); 14316e91bba0SGirish Moodalbail 14326e91bba0SGirish Moodalbail status = ipadm_delete_addr(iph, argv[optind], flags); 14336e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 14346e91bba0SGirish Moodalbail die("could not delete address: %s", 14356e91bba0SGirish Moodalbail ipadm_status2str(status)); 14366e91bba0SGirish Moodalbail } 14376e91bba0SGirish Moodalbail } 14386e91bba0SGirish Moodalbail 14396e91bba0SGirish Moodalbail /* 14406e91bba0SGirish Moodalbail * Enable an IP address based on the persistent configuration for that 14416e91bba0SGirish Moodalbail * IP address 14426e91bba0SGirish Moodalbail */ 14436e91bba0SGirish Moodalbail static void 14446e91bba0SGirish Moodalbail do_enable_addr(int argc, char *argv[], const char *use) 14456e91bba0SGirish Moodalbail { 14466e91bba0SGirish Moodalbail ipadm_status_t status; 14476e91bba0SGirish Moodalbail int index; 14486e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 14496e91bba0SGirish Moodalbail 14506e91bba0SGirish Moodalbail process_misc_addrargs(argc, argv, use, &index, &flags); 14516e91bba0SGirish Moodalbail if (flags & IPADM_OPT_PERSIST) 14526e91bba0SGirish Moodalbail die("persistent operation not supported for enable-addr"); 14536e91bba0SGirish Moodalbail 14546e91bba0SGirish Moodalbail status = ipadm_enable_addr(iph, argv[index], flags); 14556e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 14566e91bba0SGirish Moodalbail die("could not enable address: %s", ipadm_status2str(status)); 14576e91bba0SGirish Moodalbail } 14586e91bba0SGirish Moodalbail 14596e91bba0SGirish Moodalbail /* 14606e91bba0SGirish Moodalbail * Mark the address identified by addrobj 'up' 14616e91bba0SGirish Moodalbail */ 14626e91bba0SGirish Moodalbail static void 14636e91bba0SGirish Moodalbail do_up_addr(int argc, char *argv[], const char *use) 14646e91bba0SGirish Moodalbail { 14656e91bba0SGirish Moodalbail ipadm_status_t status; 14666e91bba0SGirish Moodalbail int index; 14676e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 14686e91bba0SGirish Moodalbail 14696e91bba0SGirish Moodalbail process_misc_addrargs(argc, argv, use, &index, &flags); 14706e91bba0SGirish Moodalbail status = ipadm_up_addr(iph, argv[index], flags); 14716e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 14726e91bba0SGirish Moodalbail die("Could not mark the address up: %s", 14736e91bba0SGirish Moodalbail ipadm_status2str(status)); 14746e91bba0SGirish Moodalbail } 14756e91bba0SGirish Moodalbail } 14766e91bba0SGirish Moodalbail 14776e91bba0SGirish Moodalbail /* 14786e91bba0SGirish Moodalbail * Disable the specified addrobj by removing it from active cofiguration 14796e91bba0SGirish Moodalbail */ 14806e91bba0SGirish Moodalbail static void 14816e91bba0SGirish Moodalbail do_disable_addr(int argc, char *argv[], const char *use) 14826e91bba0SGirish Moodalbail { 14836e91bba0SGirish Moodalbail ipadm_status_t status; 14846e91bba0SGirish Moodalbail int index; 14856e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 14866e91bba0SGirish Moodalbail 14876e91bba0SGirish Moodalbail process_misc_addrargs(argc, argv, use, &index, &flags); 14886e91bba0SGirish Moodalbail if (flags & IPADM_OPT_PERSIST) 14896e91bba0SGirish Moodalbail die("persistent operation not supported for disable-addr"); 14906e91bba0SGirish Moodalbail 14916e91bba0SGirish Moodalbail status = ipadm_disable_addr(iph, argv[index], flags); 14926e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 14936e91bba0SGirish Moodalbail die("could not disable address: %s", 14946e91bba0SGirish Moodalbail ipadm_status2str(status)); 14956e91bba0SGirish Moodalbail } 14966e91bba0SGirish Moodalbail } 14976e91bba0SGirish Moodalbail 14986e91bba0SGirish Moodalbail /* 14996e91bba0SGirish Moodalbail * Mark the address identified by addrobj 'down' 15006e91bba0SGirish Moodalbail */ 15016e91bba0SGirish Moodalbail static void 15026e91bba0SGirish Moodalbail do_down_addr(int argc, char *argv[], const char *use) 15036e91bba0SGirish Moodalbail { 15046e91bba0SGirish Moodalbail ipadm_status_t status; 15056e91bba0SGirish Moodalbail int index; 15066e91bba0SGirish Moodalbail uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 15076e91bba0SGirish Moodalbail 15086e91bba0SGirish Moodalbail process_misc_addrargs(argc, argv, use, &index, &flags); 15096e91bba0SGirish Moodalbail status = ipadm_down_addr(iph, argv[index], flags); 15106e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 15116e91bba0SGirish Moodalbail die("Could not mark the address down: %s", 15126e91bba0SGirish Moodalbail ipadm_status2str(status)); 15136e91bba0SGirish Moodalbail } 15146e91bba0SGirish Moodalbail 15156e91bba0SGirish Moodalbail /* 15166e91bba0SGirish Moodalbail * Restart DAD for static address. Extend lease duration for DHCP addresses 15176e91bba0SGirish Moodalbail */ 15186e91bba0SGirish Moodalbail static void 15196e91bba0SGirish Moodalbail do_refresh_addr(int argc, char *argv[], const char *use) 15206e91bba0SGirish Moodalbail { 15216e91bba0SGirish Moodalbail ipadm_status_t status; 15226e91bba0SGirish Moodalbail int option; 15236e91bba0SGirish Moodalbail uint32_t flags = 0; 15246e91bba0SGirish Moodalbail 15256e91bba0SGirish Moodalbail opterr = 0; 15266e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":i", addr_misc_longopts, 15276e91bba0SGirish Moodalbail NULL)) != -1) { 15286e91bba0SGirish Moodalbail switch (option) { 15296e91bba0SGirish Moodalbail case 'i': 15306e91bba0SGirish Moodalbail flags |= IPADM_OPT_INFORM; 15316e91bba0SGirish Moodalbail break; 15326e91bba0SGirish Moodalbail default: 15336e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 15346e91bba0SGirish Moodalbail } 15356e91bba0SGirish Moodalbail } 15366e91bba0SGirish Moodalbail if (optind != (argc - 1)) 15376e91bba0SGirish Moodalbail die("Usage: %s", use); 15386e91bba0SGirish Moodalbail 15396e91bba0SGirish Moodalbail status = ipadm_refresh_addr(iph, argv[optind], flags); 15406e91bba0SGirish Moodalbail if (status == IPADM_DHCP_IPC_TIMEOUT) 15416e91bba0SGirish Moodalbail warn_ipadmerr(status, ""); 15426e91bba0SGirish Moodalbail else if (status != IPADM_SUCCESS) 15436e91bba0SGirish Moodalbail die("could not refresh address %s", ipadm_status2str(status)); 15446e91bba0SGirish Moodalbail } 15456e91bba0SGirish Moodalbail 15466e91bba0SGirish Moodalbail static void 15476e91bba0SGirish Moodalbail sockaddr2str(const struct sockaddr_storage *ssp, char *buf, uint_t bufsize) 15486e91bba0SGirish Moodalbail { 15496e91bba0SGirish Moodalbail socklen_t socklen; 15506e91bba0SGirish Moodalbail struct sockaddr *sp = (struct sockaddr *)ssp; 15516e91bba0SGirish Moodalbail 15526e91bba0SGirish Moodalbail switch (ssp->ss_family) { 15536e91bba0SGirish Moodalbail case AF_INET: 15546e91bba0SGirish Moodalbail socklen = sizeof (struct sockaddr_in); 15556e91bba0SGirish Moodalbail break; 15566e91bba0SGirish Moodalbail case AF_INET6: 15576e91bba0SGirish Moodalbail socklen = sizeof (struct sockaddr_in6); 15586e91bba0SGirish Moodalbail break; 15596e91bba0SGirish Moodalbail default: 15606e91bba0SGirish Moodalbail (void) strlcpy(buf, STR_UNKNOWN_VAL, bufsize); 15616e91bba0SGirish Moodalbail return; 15626e91bba0SGirish Moodalbail } 15636e91bba0SGirish Moodalbail 15646e91bba0SGirish Moodalbail (void) getnameinfo(sp, socklen, buf, bufsize, NULL, 0, 15656e91bba0SGirish Moodalbail (NI_NOFQDN | NI_NUMERICHOST)); 15666e91bba0SGirish Moodalbail } 15676e91bba0SGirish Moodalbail 15686e91bba0SGirish Moodalbail static void 15696e91bba0SGirish Moodalbail flags2str(uint64_t flags, fmask_t *tbl, boolean_t is_bits, 15706e91bba0SGirish Moodalbail char *buf, uint_t bufsize) 15716e91bba0SGirish Moodalbail { 15726e91bba0SGirish Moodalbail int i; 15736e91bba0SGirish Moodalbail boolean_t first = _B_TRUE; 15746e91bba0SGirish Moodalbail 15756e91bba0SGirish Moodalbail if (is_bits) { 15766e91bba0SGirish Moodalbail for (i = 0; tbl[i].name; i++) { 15776e91bba0SGirish Moodalbail if ((flags & tbl[i].mask) == tbl[i].bits) 15786e91bba0SGirish Moodalbail (void) strlcat(buf, tbl[i].name, bufsize); 15796e91bba0SGirish Moodalbail else 15806e91bba0SGirish Moodalbail (void) strlcat(buf, "-", bufsize); 15816e91bba0SGirish Moodalbail } 15826e91bba0SGirish Moodalbail } else { 15836e91bba0SGirish Moodalbail for (i = 0; tbl[i].name; i++) { 15846e91bba0SGirish Moodalbail if ((flags & tbl[i].mask) == tbl[i].bits) { 15856e91bba0SGirish Moodalbail if (!first) 15866e91bba0SGirish Moodalbail (void) strlcat(buf, ",", bufsize); 15876e91bba0SGirish Moodalbail (void) strlcat(buf, tbl[i].name, bufsize); 15886e91bba0SGirish Moodalbail first = _B_FALSE; 15896e91bba0SGirish Moodalbail } 15906e91bba0SGirish Moodalbail } 15916e91bba0SGirish Moodalbail } 15926e91bba0SGirish Moodalbail } 15936e91bba0SGirish Moodalbail 1594550b6e40SSowmini Varadhan /* 1595550b6e40SSowmini Varadhan * return true if the address for lifname comes to us from the global zone 1596550b6e40SSowmini Varadhan * with 'allowed-ips' constraints. 1597550b6e40SSowmini Varadhan */ 1598550b6e40SSowmini Varadhan static boolean_t 1599550b6e40SSowmini Varadhan is_from_gz(const char *lifname) 1600550b6e40SSowmini Varadhan { 1601550b6e40SSowmini Varadhan ipadm_if_info_t *if_info; 1602550b6e40SSowmini Varadhan char phyname[LIFNAMSIZ], *cp; 1603550b6e40SSowmini Varadhan boolean_t ret = _B_FALSE; 1604550b6e40SSowmini Varadhan ipadm_status_t status; 1605550b6e40SSowmini Varadhan zoneid_t zoneid; 1606550b6e40SSowmini Varadhan ushort_t zflags; 1607550b6e40SSowmini Varadhan 1608550b6e40SSowmini Varadhan if ((zoneid = getzoneid()) == GLOBAL_ZONEID) 1609550b6e40SSowmini Varadhan return (_B_FALSE); /* from-gz only makes sense in a NGZ */ 1610550b6e40SSowmini Varadhan 1611550b6e40SSowmini Varadhan if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &zflags, sizeof (zflags)) < 0) 1612550b6e40SSowmini Varadhan return (_B_FALSE); 1613550b6e40SSowmini Varadhan 1614550b6e40SSowmini Varadhan if (!(zflags & ZF_NET_EXCL)) 1615550b6e40SSowmini Varadhan return (_B_TRUE); /* everything is from the GZ for shared-ip */ 1616550b6e40SSowmini Varadhan 1617550b6e40SSowmini Varadhan (void) strncpy(phyname, lifname, sizeof (phyname)); 1618550b6e40SSowmini Varadhan if ((cp = strchr(phyname, ':')) != NULL) 1619550b6e40SSowmini Varadhan *cp = '\0'; 1620550b6e40SSowmini Varadhan status = ipadm_if_info(iph, phyname, &if_info, 0, LIFC_DEFAULT); 1621550b6e40SSowmini Varadhan if (status != IPADM_SUCCESS) 1622550b6e40SSowmini Varadhan return (ret); 1623550b6e40SSowmini Varadhan 1624550b6e40SSowmini Varadhan if (if_info->ifi_cflags & IFIF_L3PROTECT) 1625550b6e40SSowmini Varadhan ret = _B_TRUE; 1626550b6e40SSowmini Varadhan if (if_info) 1627550b6e40SSowmini Varadhan ipadm_free_if_info(if_info); 1628550b6e40SSowmini Varadhan return (ret); 1629550b6e40SSowmini Varadhan } 1630550b6e40SSowmini Varadhan 16316e91bba0SGirish Moodalbail static boolean_t 16326e91bba0SGirish Moodalbail print_sa_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 16336e91bba0SGirish Moodalbail { 16346e91bba0SGirish Moodalbail show_addr_args_t *arg = ofarg->ofmt_cbarg; 16356e91bba0SGirish Moodalbail ipadm_addr_info_t *ainfo = arg->sa_info; 16366e91bba0SGirish Moodalbail char interface[LIFNAMSIZ]; 16376e91bba0SGirish Moodalbail char addrbuf[MAXPROPVALLEN]; 16386e91bba0SGirish Moodalbail char dstbuf[MAXPROPVALLEN]; 16396e91bba0SGirish Moodalbail char prefixlenstr[MAXPROPVALLEN]; 16406e91bba0SGirish Moodalbail int prefixlen; 16416e91bba0SGirish Moodalbail struct sockaddr_in *sin; 16426e91bba0SGirish Moodalbail struct sockaddr_in6 *sin6; 16436e91bba0SGirish Moodalbail sa_family_t af; 16446e91bba0SGirish Moodalbail char *phyname = NULL; 16456e91bba0SGirish Moodalbail struct ifaddrs *ifa = &ainfo->ia_ifa; 16466e91bba0SGirish Moodalbail fmask_t cflags_mask[] = { 16476e91bba0SGirish Moodalbail { "U", IA_UP, IA_UP }, 16486e91bba0SGirish Moodalbail { "u", IA_UNNUMBERED, IA_UNNUMBERED }, 16496e91bba0SGirish Moodalbail { "p", IA_PRIVATE, IA_PRIVATE }, 16506e91bba0SGirish Moodalbail { "t", IA_TEMPORARY, IA_TEMPORARY }, 16516e91bba0SGirish Moodalbail { "d", IA_DEPRECATED, IA_DEPRECATED }, 16526e91bba0SGirish Moodalbail { NULL, 0, 0 } 16536e91bba0SGirish Moodalbail }; 16546e91bba0SGirish Moodalbail fmask_t pflags_mask[] = { 16556e91bba0SGirish Moodalbail { "U", IA_UP, IA_UP }, 16566e91bba0SGirish Moodalbail { "p", IA_PRIVATE, IA_PRIVATE }, 16576e91bba0SGirish Moodalbail { "d", IA_DEPRECATED, IA_DEPRECATED }, 16586e91bba0SGirish Moodalbail { NULL, 0, 0 } 16596e91bba0SGirish Moodalbail }; 16606e91bba0SGirish Moodalbail fmask_t type[] = { 16616e91bba0SGirish Moodalbail { "static", IPADM_ADDR_STATIC, IPADM_ALL_BITS}, 16626e91bba0SGirish Moodalbail { "addrconf", IPADM_ADDR_IPV6_ADDRCONF, IPADM_ALL_BITS}, 16636e91bba0SGirish Moodalbail { "dhcp", IPADM_ADDR_DHCP, IPADM_ALL_BITS}, 16646e91bba0SGirish Moodalbail { NULL, 0, 0 } 16656e91bba0SGirish Moodalbail }; 16666e91bba0SGirish Moodalbail fmask_t addr_state[] = { 16676e91bba0SGirish Moodalbail { "disabled", IFA_DISABLED, IPADM_ALL_BITS}, 16686e91bba0SGirish Moodalbail { "duplicate", IFA_DUPLICATE, IPADM_ALL_BITS}, 16696e91bba0SGirish Moodalbail { "down", IFA_DOWN, IPADM_ALL_BITS}, 16706e91bba0SGirish Moodalbail { "tentative", IFA_TENTATIVE, IPADM_ALL_BITS}, 16716e91bba0SGirish Moodalbail { "ok", IFA_OK, IPADM_ALL_BITS}, 16726e91bba0SGirish Moodalbail { "inaccessible", IFA_INACCESSIBLE, IPADM_ALL_BITS}, 16736e91bba0SGirish Moodalbail { NULL, 0, 0 } 16746e91bba0SGirish Moodalbail }; 16756e91bba0SGirish Moodalbail 16766e91bba0SGirish Moodalbail buf[0] = '\0'; 16776e91bba0SGirish Moodalbail switch (ofarg->ofmt_id) { 16786e91bba0SGirish Moodalbail case SA_ADDROBJ: 16796e91bba0SGirish Moodalbail if (ainfo->ia_aobjname[0] == '\0') { 16806e91bba0SGirish Moodalbail (void) strncpy(interface, ifa->ifa_name, LIFNAMSIZ); 16816e91bba0SGirish Moodalbail phyname = strrchr(interface, ':'); 16826e91bba0SGirish Moodalbail if (phyname) 16836e91bba0SGirish Moodalbail *phyname = '\0'; 16846e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s/%s", interface, 16856e91bba0SGirish Moodalbail STR_UNKNOWN_VAL); 16866e91bba0SGirish Moodalbail } else { 16876e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s", ainfo->ia_aobjname); 16886e91bba0SGirish Moodalbail } 16896e91bba0SGirish Moodalbail break; 16906e91bba0SGirish Moodalbail case SA_STATE: 16916e91bba0SGirish Moodalbail flags2str(ainfo->ia_state, addr_state, _B_FALSE, 16926e91bba0SGirish Moodalbail buf, bufsize); 16936e91bba0SGirish Moodalbail break; 16946e91bba0SGirish Moodalbail case SA_TYPE: 1695550b6e40SSowmini Varadhan if (is_from_gz(ifa->ifa_name)) 1696550b6e40SSowmini Varadhan (void) snprintf(buf, bufsize, "from-gz"); 1697550b6e40SSowmini Varadhan else 1698550b6e40SSowmini Varadhan flags2str(ainfo->ia_atype, type, _B_FALSE, buf, 1699550b6e40SSowmini Varadhan bufsize); 17006e91bba0SGirish Moodalbail break; 17016e91bba0SGirish Moodalbail case SA_CURRENT: 17026e91bba0SGirish Moodalbail flags2str(ainfo->ia_cflags, cflags_mask, _B_TRUE, buf, bufsize); 17036e91bba0SGirish Moodalbail break; 17046e91bba0SGirish Moodalbail case SA_PERSISTENT: 17056e91bba0SGirish Moodalbail flags2str(ainfo->ia_pflags, pflags_mask, _B_TRUE, buf, bufsize); 17066e91bba0SGirish Moodalbail break; 17076e91bba0SGirish Moodalbail case SA_ADDR: 170864639aafSDarren Reed af = ifa->ifa_addr->sa_family; 17096e91bba0SGirish Moodalbail /* 17106e91bba0SGirish Moodalbail * If the address is 0.0.0.0 or :: and the origin is DHCP, 17116e91bba0SGirish Moodalbail * print STR_UNKNOWN_VAL. 17126e91bba0SGirish Moodalbail */ 17136e91bba0SGirish Moodalbail if (ainfo->ia_atype == IPADM_ADDR_DHCP) { 17146e91bba0SGirish Moodalbail sin = (struct sockaddr_in *)ifa->ifa_addr; 17156e91bba0SGirish Moodalbail sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 17166e91bba0SGirish Moodalbail if ((af == AF_INET && 17176e91bba0SGirish Moodalbail sin->sin_addr.s_addr == INADDR_ANY) || 17186e91bba0SGirish Moodalbail (af == AF_INET6 && 17196e91bba0SGirish Moodalbail IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) { 17206e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, STR_UNKNOWN_VAL); 17216e91bba0SGirish Moodalbail break; 17226e91bba0SGirish Moodalbail } 17236e91bba0SGirish Moodalbail } 17246e91bba0SGirish Moodalbail if (ifa->ifa_netmask == NULL) 17256e91bba0SGirish Moodalbail prefixlen = 0; 17266e91bba0SGirish Moodalbail else 17276e91bba0SGirish Moodalbail prefixlen = mask2plen(ifa->ifa_netmask); 17286e91bba0SGirish Moodalbail bzero(prefixlenstr, sizeof (prefixlenstr)); 17296e91bba0SGirish Moodalbail if (prefixlen > 0) { 17306e91bba0SGirish Moodalbail (void) snprintf(prefixlenstr, sizeof (prefixlenstr), 17316e91bba0SGirish Moodalbail "/%d", prefixlen); 17326e91bba0SGirish Moodalbail } 17336e91bba0SGirish Moodalbail bzero(addrbuf, sizeof (addrbuf)); 17346e91bba0SGirish Moodalbail bzero(dstbuf, sizeof (dstbuf)); 17356e91bba0SGirish Moodalbail if (ainfo->ia_atype == IPADM_ADDR_STATIC) { 17366e91bba0SGirish Moodalbail /* 17376e91bba0SGirish Moodalbail * Print the hostname fields if the address is not 17386e91bba0SGirish Moodalbail * in active configuration. 17396e91bba0SGirish Moodalbail */ 17406e91bba0SGirish Moodalbail if (ainfo->ia_state == IFA_DISABLED) { 17416e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s", 17426e91bba0SGirish Moodalbail ainfo->ia_sname); 17436e91bba0SGirish Moodalbail if (ainfo->ia_dname[0] != '\0') { 17446e91bba0SGirish Moodalbail (void) snprintf(dstbuf, sizeof (dstbuf), 17456e91bba0SGirish Moodalbail "->%s", ainfo->ia_dname); 17466e91bba0SGirish Moodalbail (void) strlcat(buf, dstbuf, bufsize); 17476e91bba0SGirish Moodalbail } else { 17486e91bba0SGirish Moodalbail (void) strlcat(buf, prefixlenstr, 17496e91bba0SGirish Moodalbail bufsize); 17506e91bba0SGirish Moodalbail } 17516e91bba0SGirish Moodalbail break; 17526e91bba0SGirish Moodalbail } 175308ed54f3SVasumathi Sundaram } 17546e91bba0SGirish Moodalbail /* 17556e91bba0SGirish Moodalbail * For the non-persistent case, we need to show the 17566e91bba0SGirish Moodalbail * currently configured addresses for source and 17576e91bba0SGirish Moodalbail * destination. 17586e91bba0SGirish Moodalbail */ 175908ed54f3SVasumathi Sundaram sockaddr2str((struct sockaddr_storage *)ifa->ifa_addr, 176008ed54f3SVasumathi Sundaram addrbuf, sizeof (addrbuf)); 17616e91bba0SGirish Moodalbail if (ifa->ifa_flags & IFF_POINTOPOINT) { 17626e91bba0SGirish Moodalbail sockaddr2str( 17636e91bba0SGirish Moodalbail (struct sockaddr_storage *)ifa->ifa_dstaddr, 17646e91bba0SGirish Moodalbail dstbuf, sizeof (dstbuf)); 17656e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s->%s", addrbuf, 17666e91bba0SGirish Moodalbail dstbuf); 17676e91bba0SGirish Moodalbail } else { 17686e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s%s", addrbuf, 17696e91bba0SGirish Moodalbail prefixlenstr); 17706e91bba0SGirish Moodalbail } 17716e91bba0SGirish Moodalbail break; 17726e91bba0SGirish Moodalbail default: 17736e91bba0SGirish Moodalbail die("invalid input"); 17746e91bba0SGirish Moodalbail break; 17756e91bba0SGirish Moodalbail } 17766e91bba0SGirish Moodalbail 17776e91bba0SGirish Moodalbail return (_B_TRUE); 17786e91bba0SGirish Moodalbail } 17796e91bba0SGirish Moodalbail 17806e91bba0SGirish Moodalbail /* 17816e91bba0SGirish Moodalbail * Display address information, either for the given address or 17826e91bba0SGirish Moodalbail * for all the addresses managed by ipadm. 17836e91bba0SGirish Moodalbail */ 17846e91bba0SGirish Moodalbail static void 17856e91bba0SGirish Moodalbail do_show_addr(int argc, char *argv[], const char *use) 17866e91bba0SGirish Moodalbail { 17876e91bba0SGirish Moodalbail ipadm_status_t status; 17886e91bba0SGirish Moodalbail show_addr_state_t state; 17896e91bba0SGirish Moodalbail char *def_fields_str = "addrobj,type,state,addr"; 17906e91bba0SGirish Moodalbail char *fields_str = NULL; 17916e91bba0SGirish Moodalbail ipadm_addr_info_t *ainfo; 17926e91bba0SGirish Moodalbail ipadm_addr_info_t *ptr; 17936e91bba0SGirish Moodalbail show_addr_args_t sargs; 17946e91bba0SGirish Moodalbail int option; 17956e91bba0SGirish Moodalbail ofmt_handle_t ofmt; 17966e91bba0SGirish Moodalbail ofmt_status_t oferr; 17976e91bba0SGirish Moodalbail uint_t ofmtflags = 0; 17986e91bba0SGirish Moodalbail char *aname; 17996e91bba0SGirish Moodalbail char *ifname = NULL; 18006e91bba0SGirish Moodalbail char *cp; 18016e91bba0SGirish Moodalbail boolean_t found = _B_FALSE; 18026e91bba0SGirish Moodalbail 18036e91bba0SGirish Moodalbail opterr = 0; 18046e91bba0SGirish Moodalbail state.sa_parsable = _B_FALSE; 18056e91bba0SGirish Moodalbail state.sa_persist = _B_FALSE; 18066e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, "po:", show_addr_longopts, 18076e91bba0SGirish Moodalbail NULL)) != -1) { 18086e91bba0SGirish Moodalbail switch (option) { 18096e91bba0SGirish Moodalbail case 'p': 18106e91bba0SGirish Moodalbail state.sa_parsable = _B_TRUE; 18116e91bba0SGirish Moodalbail break; 18126e91bba0SGirish Moodalbail case 'o': 18136e91bba0SGirish Moodalbail fields_str = optarg; 18146e91bba0SGirish Moodalbail break; 18156e91bba0SGirish Moodalbail default: 18166e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 18176e91bba0SGirish Moodalbail break; 18186e91bba0SGirish Moodalbail } 18196e91bba0SGirish Moodalbail } 18206e91bba0SGirish Moodalbail if (state.sa_parsable && fields_str == NULL) 18216e91bba0SGirish Moodalbail die("-p requires -o"); 18226e91bba0SGirish Moodalbail 18236e91bba0SGirish Moodalbail if (optind == argc - 1) { 18246e91bba0SGirish Moodalbail aname = argv[optind]; 18256e91bba0SGirish Moodalbail if ((cp = strchr(aname, '/')) == NULL) 18266e91bba0SGirish Moodalbail die("Invalid address object name provided"); 18276e91bba0SGirish Moodalbail if (*(cp + 1) == '\0') { 18286e91bba0SGirish Moodalbail ifname = aname; 18296e91bba0SGirish Moodalbail *cp = '\0'; 18306e91bba0SGirish Moodalbail aname = NULL; 18316e91bba0SGirish Moodalbail } 18326e91bba0SGirish Moodalbail } else if (optind == argc) { 18336e91bba0SGirish Moodalbail aname = NULL; 18346e91bba0SGirish Moodalbail } else { 18356e91bba0SGirish Moodalbail die("Usage: %s", use); 18366e91bba0SGirish Moodalbail } 18376e91bba0SGirish Moodalbail 18386e91bba0SGirish Moodalbail if (state.sa_parsable) 18396e91bba0SGirish Moodalbail ofmtflags |= OFMT_PARSABLE; 18406e91bba0SGirish Moodalbail if (fields_str == NULL) 18416e91bba0SGirish Moodalbail fields_str = def_fields_str; 18426e91bba0SGirish Moodalbail oferr = ofmt_open(fields_str, show_addr_fields, ofmtflags, 0, &ofmt); 18436e91bba0SGirish Moodalbail 18446e91bba0SGirish Moodalbail ipadm_ofmt_check(oferr, state.sa_parsable, ofmt); 18456e91bba0SGirish Moodalbail state.sa_ofmt = ofmt; 18466e91bba0SGirish Moodalbail 18476e91bba0SGirish Moodalbail status = ipadm_addr_info(iph, ifname, &ainfo, 0, LIFC_DEFAULT); 18486e91bba0SGirish Moodalbail /* 18496e91bba0SGirish Moodalbail * Return without printing any error, if no addresses were found, 18506e91bba0SGirish Moodalbail * for the case where all addresses are requested. 18516e91bba0SGirish Moodalbail */ 18526e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) 18536e91bba0SGirish Moodalbail die("Could not get address: %s", ipadm_status2str(status)); 18546e91bba0SGirish Moodalbail if (ainfo == NULL) { 18556e91bba0SGirish Moodalbail ofmt_close(ofmt); 18566e91bba0SGirish Moodalbail return; 18576e91bba0SGirish Moodalbail } 18586e91bba0SGirish Moodalbail 18596e91bba0SGirish Moodalbail bzero(&sargs, sizeof (sargs)); 18606e91bba0SGirish Moodalbail sargs.sa_state = &state; 18616e91bba0SGirish Moodalbail for (ptr = ainfo; ptr != NULL; ptr = IA_NEXT(ptr)) { 18626e91bba0SGirish Moodalbail sargs.sa_info = ptr; 18636e91bba0SGirish Moodalbail if (aname != NULL) { 18646e91bba0SGirish Moodalbail if (strcmp(sargs.sa_info->ia_aobjname, aname) != 0) 18656e91bba0SGirish Moodalbail continue; 18666e91bba0SGirish Moodalbail found = _B_TRUE; 18676e91bba0SGirish Moodalbail } 18686e91bba0SGirish Moodalbail ofmt_print(state.sa_ofmt, &sargs); 18696e91bba0SGirish Moodalbail } 18706e91bba0SGirish Moodalbail if (ainfo) 18716e91bba0SGirish Moodalbail ipadm_free_addr_info(ainfo); 18726e91bba0SGirish Moodalbail if (aname != NULL && !found) 18736e91bba0SGirish Moodalbail die("Address object not found"); 18746e91bba0SGirish Moodalbail } 18756e91bba0SGirish Moodalbail 18766e91bba0SGirish Moodalbail static boolean_t 18776e91bba0SGirish Moodalbail print_si_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) 18786e91bba0SGirish Moodalbail { 18796e91bba0SGirish Moodalbail show_if_args_t *arg = ofarg->ofmt_cbarg; 18806e91bba0SGirish Moodalbail ipadm_if_info_t *ifinfo = arg->si_info; 18816e91bba0SGirish Moodalbail char *ifname = ifinfo->ifi_name; 18826e91bba0SGirish Moodalbail fmask_t intf_state[] = { 18836e91bba0SGirish Moodalbail { "ok", IFIS_OK, IPADM_ALL_BITS}, 18846e91bba0SGirish Moodalbail { "down", IFIS_DOWN, IPADM_ALL_BITS}, 18856e91bba0SGirish Moodalbail { "disabled", IFIS_DISABLED, IPADM_ALL_BITS}, 18866e91bba0SGirish Moodalbail { "failed", IFIS_FAILED, IPADM_ALL_BITS}, 18876e91bba0SGirish Moodalbail { "offline", IFIS_OFFLINE, IPADM_ALL_BITS}, 18886e91bba0SGirish Moodalbail { NULL, 0, 0 } 18896e91bba0SGirish Moodalbail }; 18906e91bba0SGirish Moodalbail fmask_t intf_pflags[] = { 18916e91bba0SGirish Moodalbail { "s", IFIF_STANDBY, IFIF_STANDBY }, 18926e91bba0SGirish Moodalbail { "4", IFIF_IPV4, IFIF_IPV4 }, 18936e91bba0SGirish Moodalbail { "6", IFIF_IPV6, IFIF_IPV6 }, 18946e91bba0SGirish Moodalbail { NULL, 0, 0 } 18956e91bba0SGirish Moodalbail }; 18966e91bba0SGirish Moodalbail fmask_t intf_cflags[] = { 18976e91bba0SGirish Moodalbail { "b", IFIF_BROADCAST, IFIF_BROADCAST }, 18986e91bba0SGirish Moodalbail { "m", IFIF_MULTICAST, IFIF_MULTICAST }, 18996e91bba0SGirish Moodalbail { "p", IFIF_POINTOPOINT, IFIF_POINTOPOINT}, 19006e91bba0SGirish Moodalbail { "v", IFIF_VIRTUAL, IFIF_VIRTUAL }, 19016e91bba0SGirish Moodalbail { "I", IFIF_IPMP, IFIF_IPMP }, 19026e91bba0SGirish Moodalbail { "s", IFIF_STANDBY, IFIF_STANDBY }, 19036e91bba0SGirish Moodalbail { "i", IFIF_INACTIVE, IFIF_INACTIVE }, 19046e91bba0SGirish Moodalbail { "V", IFIF_VRRP, IFIF_VRRP }, 19056e91bba0SGirish Moodalbail { "a", IFIF_NOACCEPT, IFIF_NOACCEPT }, 1906550b6e40SSowmini Varadhan { "Z", IFIF_L3PROTECT, IFIF_L3PROTECT }, 19076e91bba0SGirish Moodalbail { "4", IFIF_IPV4, IFIF_IPV4 }, 19086e91bba0SGirish Moodalbail { "6", IFIF_IPV6, IFIF_IPV6 }, 19096e91bba0SGirish Moodalbail { NULL, 0, 0 } 19106e91bba0SGirish Moodalbail }; 19116e91bba0SGirish Moodalbail 19126e91bba0SGirish Moodalbail buf[0] = '\0'; 19136e91bba0SGirish Moodalbail switch (ofarg->ofmt_id) { 19146e91bba0SGirish Moodalbail case SI_IFNAME: 19156e91bba0SGirish Moodalbail (void) snprintf(buf, bufsize, "%s", ifname); 19166e91bba0SGirish Moodalbail break; 19176e91bba0SGirish Moodalbail case SI_STATE: 19186e91bba0SGirish Moodalbail flags2str(ifinfo->ifi_state, intf_state, _B_FALSE, 19196e91bba0SGirish Moodalbail buf, bufsize); 19206e91bba0SGirish Moodalbail break; 19216e91bba0SGirish Moodalbail case SI_CURRENT: 19226e91bba0SGirish Moodalbail flags2str(ifinfo->ifi_cflags, intf_cflags, _B_TRUE, 19236e91bba0SGirish Moodalbail buf, bufsize); 19246e91bba0SGirish Moodalbail break; 19256e91bba0SGirish Moodalbail case SI_PERSISTENT: 19266e91bba0SGirish Moodalbail flags2str(ifinfo->ifi_pflags, intf_pflags, _B_TRUE, 19276e91bba0SGirish Moodalbail buf, bufsize); 19286e91bba0SGirish Moodalbail break; 19296e91bba0SGirish Moodalbail default: 19306e91bba0SGirish Moodalbail die("invalid input"); 19316e91bba0SGirish Moodalbail break; 19326e91bba0SGirish Moodalbail } 19336e91bba0SGirish Moodalbail 19346e91bba0SGirish Moodalbail return (_B_TRUE); 19356e91bba0SGirish Moodalbail } 19366e91bba0SGirish Moodalbail 19376e91bba0SGirish Moodalbail /* 19386e91bba0SGirish Moodalbail * Display interface information, either for the given interface or 19396e91bba0SGirish Moodalbail * for all the interfaces in the system. 19406e91bba0SGirish Moodalbail */ 19416e91bba0SGirish Moodalbail static void 19426e91bba0SGirish Moodalbail do_show_if(int argc, char *argv[], const char *use) 19436e91bba0SGirish Moodalbail { 19446e91bba0SGirish Moodalbail ipadm_status_t status; 19456e91bba0SGirish Moodalbail show_if_state_t state; 19466e91bba0SGirish Moodalbail char *fields_str = NULL; 19476e91bba0SGirish Moodalbail ipadm_if_info_t *if_info, *ptr; 19486e91bba0SGirish Moodalbail show_if_args_t sargs; 19496e91bba0SGirish Moodalbail int option; 19506e91bba0SGirish Moodalbail ofmt_handle_t ofmt; 19516e91bba0SGirish Moodalbail ofmt_status_t oferr; 19526e91bba0SGirish Moodalbail uint_t ofmtflags = 0; 19536e91bba0SGirish Moodalbail char *ifname = NULL; 19546e91bba0SGirish Moodalbail 19556e91bba0SGirish Moodalbail opterr = 0; 19566e91bba0SGirish Moodalbail state.si_parsable = _B_FALSE; 19576e91bba0SGirish Moodalbail 19586e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, "po:", show_if_longopts, 19596e91bba0SGirish Moodalbail NULL)) != -1) { 19606e91bba0SGirish Moodalbail switch (option) { 19616e91bba0SGirish Moodalbail case 'p': 19626e91bba0SGirish Moodalbail state.si_parsable = _B_TRUE; 19636e91bba0SGirish Moodalbail break; 19646e91bba0SGirish Moodalbail case 'o': 19656e91bba0SGirish Moodalbail fields_str = optarg; 19666e91bba0SGirish Moodalbail break; 19676e91bba0SGirish Moodalbail default: 19686e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 19696e91bba0SGirish Moodalbail break; 19706e91bba0SGirish Moodalbail } 19716e91bba0SGirish Moodalbail } 19726e91bba0SGirish Moodalbail if (optind == argc - 1) 19736e91bba0SGirish Moodalbail ifname = argv[optind]; 19746e91bba0SGirish Moodalbail else if (optind != argc) 19756e91bba0SGirish Moodalbail die("Usage: %s", use); 19766e91bba0SGirish Moodalbail if (state.si_parsable) 19776e91bba0SGirish Moodalbail ofmtflags |= OFMT_PARSABLE; 19786e91bba0SGirish Moodalbail oferr = ofmt_open(fields_str, show_if_fields, ofmtflags, 0, &ofmt); 19796e91bba0SGirish Moodalbail ipadm_ofmt_check(oferr, state.si_parsable, ofmt); 19806e91bba0SGirish Moodalbail state.si_ofmt = ofmt; 19816e91bba0SGirish Moodalbail bzero(&sargs, sizeof (sargs)); 19826e91bba0SGirish Moodalbail sargs.si_state = &state; 19836e91bba0SGirish Moodalbail status = ipadm_if_info(iph, ifname, &if_info, 0, LIFC_DEFAULT); 19846e91bba0SGirish Moodalbail /* 19856e91bba0SGirish Moodalbail * Return without printing any error, if no addresses were found. 19866e91bba0SGirish Moodalbail */ 19876e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 19886e91bba0SGirish Moodalbail die("Could not get interface(s): %s", 19896e91bba0SGirish Moodalbail ipadm_status2str(status)); 19906e91bba0SGirish Moodalbail } 19916e91bba0SGirish Moodalbail 19926e91bba0SGirish Moodalbail for (ptr = if_info; ptr; ptr = ptr->ifi_next) { 19936e91bba0SGirish Moodalbail sargs.si_info = ptr; 19946e91bba0SGirish Moodalbail ofmt_print(state.si_ofmt, &sargs); 19956e91bba0SGirish Moodalbail } 19966e91bba0SGirish Moodalbail if (if_info) 19976e91bba0SGirish Moodalbail ipadm_free_if_info(if_info); 19986e91bba0SGirish Moodalbail } 19996e91bba0SGirish Moodalbail 20006e91bba0SGirish Moodalbail /* 20016e91bba0SGirish Moodalbail * set/reset the address property for a given address 20026e91bba0SGirish Moodalbail */ 20036e91bba0SGirish Moodalbail static void 20046e91bba0SGirish Moodalbail set_addrprop(int argc, char **argv, boolean_t reset, const char *use) 20056e91bba0SGirish Moodalbail { 20066e91bba0SGirish Moodalbail int option; 20076e91bba0SGirish Moodalbail ipadm_status_t status = IPADM_SUCCESS; 20086e91bba0SGirish Moodalbail boolean_t p_arg = _B_FALSE; 20096e91bba0SGirish Moodalbail char *nv, *aobjname; 20106e91bba0SGirish Moodalbail char *prop_name, *prop_val; 20116e91bba0SGirish Moodalbail uint_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; 20126e91bba0SGirish Moodalbail 20136e91bba0SGirish Moodalbail opterr = 0; 20146e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":i:p:t", set_ifprop_longopts, 20156e91bba0SGirish Moodalbail NULL)) != -1) { 20166e91bba0SGirish Moodalbail switch (option) { 20176e91bba0SGirish Moodalbail case 'p': 20186e91bba0SGirish Moodalbail if (p_arg) 20196e91bba0SGirish Moodalbail die("-p must be specified once only"); 20206e91bba0SGirish Moodalbail p_arg = _B_TRUE; 20216e91bba0SGirish Moodalbail 20226e91bba0SGirish Moodalbail ipadm_check_propstr(optarg, reset, use); 20236e91bba0SGirish Moodalbail nv = optarg; 20246e91bba0SGirish Moodalbail break; 20256e91bba0SGirish Moodalbail case 't': 20266e91bba0SGirish Moodalbail flags &= ~IPADM_OPT_PERSIST; 20276e91bba0SGirish Moodalbail break; 20286e91bba0SGirish Moodalbail default: 20296e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 20306e91bba0SGirish Moodalbail } 20316e91bba0SGirish Moodalbail } 20326e91bba0SGirish Moodalbail 20336e91bba0SGirish Moodalbail if (!p_arg || optind != (argc - 1)) 20346e91bba0SGirish Moodalbail die("Usage: %s", use); 20356e91bba0SGirish Moodalbail 20366e91bba0SGirish Moodalbail prop_name = nv; 20376e91bba0SGirish Moodalbail prop_val = strchr(nv, '='); 20386e91bba0SGirish Moodalbail if (prop_val != NULL) 20396e91bba0SGirish Moodalbail *prop_val++ = '\0'; 20406e91bba0SGirish Moodalbail aobjname = argv[optind]; 20416e91bba0SGirish Moodalbail if (reset) 20426e91bba0SGirish Moodalbail flags |= IPADM_OPT_DEFAULT; 20436e91bba0SGirish Moodalbail status = ipadm_set_addrprop(iph, prop_name, prop_val, aobjname, flags); 20446e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 20456e91bba0SGirish Moodalbail if (reset) 20466e91bba0SGirish Moodalbail die("reset-addrprop: %s: %s", prop_name, 20476e91bba0SGirish Moodalbail ipadm_status2str(status)); 20486e91bba0SGirish Moodalbail else 20496e91bba0SGirish Moodalbail die("set-addrprop: %s: %s", prop_name, 20506e91bba0SGirish Moodalbail ipadm_status2str(status)); 20516e91bba0SGirish Moodalbail } 20526e91bba0SGirish Moodalbail } 20536e91bba0SGirish Moodalbail 20546e91bba0SGirish Moodalbail /* 20556e91bba0SGirish Moodalbail * Sets a property on an address object. 20566e91bba0SGirish Moodalbail */ 20576e91bba0SGirish Moodalbail static void 20586e91bba0SGirish Moodalbail do_set_addrprop(int argc, char **argv, const char *use) 20596e91bba0SGirish Moodalbail { 20606e91bba0SGirish Moodalbail set_addrprop(argc, argv, _B_FALSE, use); 20616e91bba0SGirish Moodalbail } 20626e91bba0SGirish Moodalbail 20636e91bba0SGirish Moodalbail /* 20646e91bba0SGirish Moodalbail * Resets a property to its default value on an address object. 20656e91bba0SGirish Moodalbail */ 20666e91bba0SGirish Moodalbail static void 20676e91bba0SGirish Moodalbail do_reset_addrprop(int argc, char **argv, const char *use) 20686e91bba0SGirish Moodalbail { 20696e91bba0SGirish Moodalbail set_addrprop(argc, argv, _B_TRUE, use); 20706e91bba0SGirish Moodalbail } 20716e91bba0SGirish Moodalbail 20726e91bba0SGirish Moodalbail /* 20736e91bba0SGirish Moodalbail * Display information for all or specific address properties, either for a 20746e91bba0SGirish Moodalbail * given address or for all the addresses in the system. 20756e91bba0SGirish Moodalbail */ 20766e91bba0SGirish Moodalbail static void 20776e91bba0SGirish Moodalbail do_show_addrprop(int argc, char *argv[], const char *use) 20786e91bba0SGirish Moodalbail { 20796e91bba0SGirish Moodalbail int option; 20806e91bba0SGirish Moodalbail nvlist_t *proplist = NULL; 20816e91bba0SGirish Moodalbail char *fields_str = NULL; 20826e91bba0SGirish Moodalbail show_prop_state_t state; 20836e91bba0SGirish Moodalbail ofmt_handle_t ofmt; 20846e91bba0SGirish Moodalbail ofmt_status_t oferr; 20856e91bba0SGirish Moodalbail uint_t ofmtflags = 0; 20866e91bba0SGirish Moodalbail char *aobjname; 20876e91bba0SGirish Moodalbail char *ifname = NULL; 20886e91bba0SGirish Moodalbail char *cp; 20896e91bba0SGirish Moodalbail 20906e91bba0SGirish Moodalbail opterr = 0; 20916e91bba0SGirish Moodalbail bzero(&state, sizeof (state)); 20926e91bba0SGirish Moodalbail state.sps_propval = NULL; 20936e91bba0SGirish Moodalbail state.sps_parsable = _B_FALSE; 20946e91bba0SGirish Moodalbail state.sps_addrprop = _B_TRUE; 20956e91bba0SGirish Moodalbail state.sps_proto = MOD_PROTO_NONE; 20966e91bba0SGirish Moodalbail state.sps_status = state.sps_retstatus = IPADM_SUCCESS; 20976e91bba0SGirish Moodalbail while ((option = getopt_long(argc, argv, ":p:i:cPo:", 20986e91bba0SGirish Moodalbail show_prop_longopts, NULL)) != -1) { 20996e91bba0SGirish Moodalbail switch (option) { 21006e91bba0SGirish Moodalbail case 'p': 21016e91bba0SGirish Moodalbail if (ipadm_str2nvlist(optarg, &proplist, 21026e91bba0SGirish Moodalbail IPADM_NORVAL) != 0) 21036e91bba0SGirish Moodalbail die("invalid interface properties specified"); 21046e91bba0SGirish Moodalbail break; 21056e91bba0SGirish Moodalbail case 'c': 21066e91bba0SGirish Moodalbail state.sps_parsable = _B_TRUE; 21076e91bba0SGirish Moodalbail break; 21086e91bba0SGirish Moodalbail case 'o': 21096e91bba0SGirish Moodalbail fields_str = optarg; 21106e91bba0SGirish Moodalbail break; 21116e91bba0SGirish Moodalbail default: 21126e91bba0SGirish Moodalbail die_opterr(optopt, option, use); 21136e91bba0SGirish Moodalbail break; 21146e91bba0SGirish Moodalbail } 21156e91bba0SGirish Moodalbail } 21166e91bba0SGirish Moodalbail if (optind == argc - 1) { 21176e91bba0SGirish Moodalbail aobjname = argv[optind]; 21186e91bba0SGirish Moodalbail cp = strchr(aobjname, '/'); 21196e91bba0SGirish Moodalbail if (cp == NULL) 21206e91bba0SGirish Moodalbail die("Invalid address object name provided"); 21216e91bba0SGirish Moodalbail if (*(cp + 1) == '\0') { 21226e91bba0SGirish Moodalbail ifname = aobjname; 21236e91bba0SGirish Moodalbail *cp = '\0'; 21246e91bba0SGirish Moodalbail aobjname = NULL; 21256e91bba0SGirish Moodalbail } 21266e91bba0SGirish Moodalbail } else if (optind == argc) { 21276e91bba0SGirish Moodalbail aobjname = NULL; 21286e91bba0SGirish Moodalbail } else { 21296e91bba0SGirish Moodalbail die("Usage: %s", use); 21306e91bba0SGirish Moodalbail } 21316e91bba0SGirish Moodalbail state.sps_proplist = proplist; 21326e91bba0SGirish Moodalbail if (state.sps_parsable) 21336e91bba0SGirish Moodalbail ofmtflags |= OFMT_PARSABLE; 21346e91bba0SGirish Moodalbail oferr = ofmt_open(fields_str, addrprop_fields, ofmtflags, 0, &ofmt); 21356e91bba0SGirish Moodalbail ipadm_ofmt_check(oferr, state.sps_parsable, ofmt); 21366e91bba0SGirish Moodalbail state.sps_ofmt = ofmt; 21376e91bba0SGirish Moodalbail 21386e91bba0SGirish Moodalbail if (aobjname != NULL) { 21396e91bba0SGirish Moodalbail (void) strlcpy(state.sps_aobjname, aobjname, 21406e91bba0SGirish Moodalbail sizeof (state.sps_aobjname)); 21416e91bba0SGirish Moodalbail show_properties(&state, IPADMPROP_CLASS_ADDR); 21426e91bba0SGirish Moodalbail } else { 21436e91bba0SGirish Moodalbail ipadm_addr_info_t *ainfop = NULL; 21446e91bba0SGirish Moodalbail ipadm_addr_info_t *ptr; 21456e91bba0SGirish Moodalbail ipadm_status_t status; 21466e91bba0SGirish Moodalbail 21476e91bba0SGirish Moodalbail status = ipadm_addr_info(iph, ifname, &ainfop, 0, LIFC_DEFAULT); 21486e91bba0SGirish Moodalbail /* 21496e91bba0SGirish Moodalbail * Return without printing any error, if no addresses were 21506e91bba0SGirish Moodalbail * found. 21516e91bba0SGirish Moodalbail */ 21526e91bba0SGirish Moodalbail if (status == IPADM_NOTFOUND) 21536e91bba0SGirish Moodalbail return; 21546e91bba0SGirish Moodalbail if (status != IPADM_SUCCESS) { 21556e91bba0SGirish Moodalbail die("Error retrieving address: %s", 21566e91bba0SGirish Moodalbail ipadm_status2str(status)); 21576e91bba0SGirish Moodalbail } 21586e91bba0SGirish Moodalbail for (ptr = ainfop; ptr; ptr = IA_NEXT(ptr)) { 21596e91bba0SGirish Moodalbail aobjname = ptr->ia_aobjname; 21606e91bba0SGirish Moodalbail if (aobjname[0] == '\0' || 21616e91bba0SGirish Moodalbail ptr->ia_atype == IPADM_ADDR_IPV6_ADDRCONF) { 21626e91bba0SGirish Moodalbail continue; 21636e91bba0SGirish Moodalbail } 21646e91bba0SGirish Moodalbail (void) strlcpy(state.sps_aobjname, aobjname, 21656e91bba0SGirish Moodalbail sizeof (state.sps_aobjname)); 21666e91bba0SGirish Moodalbail show_properties(&state, IPADMPROP_CLASS_ADDR); 21676e91bba0SGirish Moodalbail } 21686e91bba0SGirish Moodalbail ipadm_free_addr_info(ainfop); 21696e91bba0SGirish Moodalbail } 21706e91bba0SGirish Moodalbail nvlist_free(proplist); 21716e91bba0SGirish Moodalbail ofmt_close(ofmt); 21726e91bba0SGirish Moodalbail if (state.sps_retstatus != IPADM_SUCCESS) { 21736e91bba0SGirish Moodalbail ipadm_close(iph); 21746e91bba0SGirish Moodalbail exit(EXIT_FAILURE); 21756e91bba0SGirish Moodalbail } 21766e91bba0SGirish Moodalbail } 21776e91bba0SGirish Moodalbail 21786e91bba0SGirish Moodalbail static void 21796e91bba0SGirish Moodalbail ipadm_ofmt_check(ofmt_status_t oferr, boolean_t parsable, 21806e91bba0SGirish Moodalbail ofmt_handle_t ofmt) 21816e91bba0SGirish Moodalbail { 21826e91bba0SGirish Moodalbail char buf[OFMT_BUFSIZE]; 21836e91bba0SGirish Moodalbail 21846e91bba0SGirish Moodalbail if (oferr == OFMT_SUCCESS) 21856e91bba0SGirish Moodalbail return; 21866e91bba0SGirish Moodalbail (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf)); 21876e91bba0SGirish Moodalbail /* 21886e91bba0SGirish Moodalbail * All errors are considered fatal in parsable mode. 21896e91bba0SGirish Moodalbail * NOMEM errors are always fatal, regardless of mode. 21906e91bba0SGirish Moodalbail * For other errors, we print diagnostics in human-readable 21916e91bba0SGirish Moodalbail * mode and processs what we can. 21926e91bba0SGirish Moodalbail */ 21936e91bba0SGirish Moodalbail if (parsable || oferr == OFMT_ENOFIELDS) { 21946e91bba0SGirish Moodalbail ofmt_close(ofmt); 21956e91bba0SGirish Moodalbail die(buf); 21966e91bba0SGirish Moodalbail } else { 21976e91bba0SGirish Moodalbail warn(buf); 21986e91bba0SGirish Moodalbail } 21996e91bba0SGirish Moodalbail } 22006e91bba0SGirish Moodalbail 22016e91bba0SGirish Moodalbail /* 22026e91bba0SGirish Moodalbail * check if the `pstr' adheres to following syntax 22036e91bba0SGirish Moodalbail * - prop=<value[,...]> (for set) 22046e91bba0SGirish Moodalbail * - prop (for reset) 22056e91bba0SGirish Moodalbail */ 22066e91bba0SGirish Moodalbail static void 22076e91bba0SGirish Moodalbail ipadm_check_propstr(const char *pstr, boolean_t reset, const char *use) 22086e91bba0SGirish Moodalbail { 22096e91bba0SGirish Moodalbail char *nv; 22106e91bba0SGirish Moodalbail 22116e91bba0SGirish Moodalbail nv = strchr(pstr, '='); 22126e91bba0SGirish Moodalbail if (reset) { 22136e91bba0SGirish Moodalbail if (nv != NULL) 22146e91bba0SGirish Moodalbail die("incorrect syntax used for -p.\n%s", use); 22156e91bba0SGirish Moodalbail } else { 22166e91bba0SGirish Moodalbail if (nv == NULL || *++nv == '\0') 22176e91bba0SGirish Moodalbail die("please specify the value to be set.\n%s", use); 22186e91bba0SGirish Moodalbail nv = strchr(nv, '='); 22196e91bba0SGirish Moodalbail /* cannot have multiple 'prop=val' for single -p */ 22206e91bba0SGirish Moodalbail if (nv != NULL) 22216e91bba0SGirish Moodalbail die("cannot specify more than one prop=val at " 22226e91bba0SGirish Moodalbail "a time.\n%s", use); 22236e91bba0SGirish Moodalbail } 22246e91bba0SGirish Moodalbail } 2225