1dbed73cbSSangeeta Misra /* 2dbed73cbSSangeeta Misra * CDDL HEADER START 3dbed73cbSSangeeta Misra * 4dbed73cbSSangeeta Misra * The contents of this file are subject to the terms of the 5dbed73cbSSangeeta Misra * Common Development and Distribution License (the "License"). 6dbed73cbSSangeeta Misra * You may not use this file except in compliance with the License. 7dbed73cbSSangeeta Misra * 8dbed73cbSSangeeta Misra * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9dbed73cbSSangeeta Misra * or http://www.opensolaris.org/os/licensing. 10dbed73cbSSangeeta Misra * See the License for the specific language governing permissions 11dbed73cbSSangeeta Misra * and limitations under the License. 12dbed73cbSSangeeta Misra * 13dbed73cbSSangeeta Misra * When distributing Covered Code, include this CDDL HEADER in each 14dbed73cbSSangeeta Misra * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15dbed73cbSSangeeta Misra * If applicable, add the following below this CDDL HEADER, with the 16dbed73cbSSangeeta Misra * fields enclosed by brackets "[]" replaced with your own identifying 17dbed73cbSSangeeta Misra * information: Portions Copyright [yyyy] [name of copyright owner] 18dbed73cbSSangeeta Misra * 19dbed73cbSSangeeta Misra * CDDL HEADER END 20dbed73cbSSangeeta Misra */ 21dbed73cbSSangeeta Misra 22dbed73cbSSangeeta Misra /* 23dbed73cbSSangeeta Misra * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24dbed73cbSSangeeta Misra * Use is subject to license terms. 25*33f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved. 26dbed73cbSSangeeta Misra */ 27dbed73cbSSangeeta Misra 28dbed73cbSSangeeta Misra #include <stdio.h> 29dbed73cbSSangeeta Misra #include <unistd.h> 30dbed73cbSSangeeta Misra #include <stdlib.h> 31dbed73cbSSangeeta Misra #include <strings.h> 32dbed73cbSSangeeta Misra #include <errno.h> 33dbed73cbSSangeeta Misra #include <sys/types.h> 34dbed73cbSSangeeta Misra #include <sys/socket.h> 35dbed73cbSSangeeta Misra #include <netinet/in.h> 36dbed73cbSSangeeta Misra #include <arpa/inet.h> 37dbed73cbSSangeeta Misra #include <sys/list.h> 38dbed73cbSSangeeta Misra #include <netdb.h> 39dbed73cbSSangeeta Misra #include <ofmt.h> 40dbed73cbSSangeeta Misra #include <assert.h> 41dbed73cbSSangeeta Misra #include <libilb.h> 42dbed73cbSSangeeta Misra #include "ilbadm.h" 43dbed73cbSSangeeta Misra 44dbed73cbSSangeeta Misra static ilbadm_key_name_t rl_incoming_keys[] = { 45dbed73cbSSangeeta Misra {ILB_KEY_VIP, "vip", ""}, 46dbed73cbSSangeeta Misra {ILB_KEY_PORT, "port", ""}, 47dbed73cbSSangeeta Misra {ILB_KEY_PROTOCOL, "protocol", "prot"}, 48dbed73cbSSangeeta Misra {ILB_KEY_BAD, "", ""} 49dbed73cbSSangeeta Misra }; 50dbed73cbSSangeeta Misra static ilbadm_key_name_t rl_method_keys[] = { 51dbed73cbSSangeeta Misra {ILB_KEY_ALGORITHM, "lbalg", "algo"}, 52dbed73cbSSangeeta Misra {ILB_KEY_TYPE, "type", "topo"}, 53dbed73cbSSangeeta Misra {ILB_KEY_SRC, "proxy-src", "nat-src"}, 54dbed73cbSSangeeta Misra {ILB_KEY_STICKY, "pmask", "persist"}, 55dbed73cbSSangeeta Misra {ILB_KEY_BAD, "", ""} 56dbed73cbSSangeeta Misra }; 57dbed73cbSSangeeta Misra static ilbadm_key_name_t rl_outgoing_keys[] = { 58dbed73cbSSangeeta Misra {ILB_KEY_SERVERGROUP, "servergroup", "sg"}, 59dbed73cbSSangeeta Misra {ILB_KEY_BAD, "", ""} 60dbed73cbSSangeeta Misra }; 61dbed73cbSSangeeta Misra static ilbadm_key_name_t rl_healthchk_keys[] = { 62dbed73cbSSangeeta Misra {ILB_KEY_HEALTHCHECK, "hc-name", "hcn"}, 63dbed73cbSSangeeta Misra {ILB_KEY_HCPORT, "hc-port", "hcp"}, 64dbed73cbSSangeeta Misra {ILB_KEY_BAD, "", ""} 65dbed73cbSSangeeta Misra }; 66dbed73cbSSangeeta Misra static ilbadm_key_name_t rl_timer_keys[] = { 67dbed73cbSSangeeta Misra {ILB_KEY_CONNDRAIN, "conn-drain", ""}, 68dbed73cbSSangeeta Misra {ILB_KEY_NAT_TO, "nat-timeout", ""}, 69dbed73cbSSangeeta Misra {ILB_KEY_STICKY_TO, "persist-timeout", ""}, 70dbed73cbSSangeeta Misra {ILB_KEY_BAD, "", ""} 71dbed73cbSSangeeta Misra }; 72dbed73cbSSangeeta Misra 73dbed73cbSSangeeta Misra static ilbadm_key_name_t *all_keys[] = { 74dbed73cbSSangeeta Misra rl_incoming_keys, rl_method_keys, rl_outgoing_keys, 75dbed73cbSSangeeta Misra rl_healthchk_keys, rl_timer_keys, NULL 76dbed73cbSSangeeta Misra }; 77dbed73cbSSangeeta Misra 78dbed73cbSSangeeta Misra 79dbed73cbSSangeeta Misra /* field ids for of_* functions */ 80dbed73cbSSangeeta Misra #define OF_IP_VIP 0 81dbed73cbSSangeeta Misra #define OF_IP_PROXYSRC 1 82dbed73cbSSangeeta Misra #define OF_IP_STICKYMASK 2 83dbed73cbSSangeeta Misra 84dbed73cbSSangeeta Misra #define OF_STR_RNAME 0 85dbed73cbSSangeeta Misra #define OF_STR_HCNAME 1 86dbed73cbSSangeeta Misra #define OF_STR_SGNAME 2 87dbed73cbSSangeeta Misra #define OF_STR_INTERFACE 3 88dbed73cbSSangeeta Misra 89dbed73cbSSangeeta Misra #define OF_PORT 0 90dbed73cbSSangeeta Misra #define OF_HCPORT 1 91dbed73cbSSangeeta Misra 92dbed73cbSSangeeta Misra #define OF_T_CONN 0 93dbed73cbSSangeeta Misra #define OF_T_NAT 1 94dbed73cbSSangeeta Misra #define OF_T_STICKY 2 95dbed73cbSSangeeta Misra 96dbed73cbSSangeeta Misra #define OF_SRV_ID 0 97dbed73cbSSangeeta Misra #define OF_SRV_ADDR 1 98dbed73cbSSangeeta Misra #define OF_SRV_PORT 2 99dbed73cbSSangeeta Misra #define OF_SRV_STATUS 3 100dbed73cbSSangeeta Misra #define OF_SRV_RNAME 4 101dbed73cbSSangeeta Misra #define OF_SRV_SGNAME 5 102dbed73cbSSangeeta Misra #define OF_SRV_HOSTNAME 6 103dbed73cbSSangeeta Misra 104dbed73cbSSangeeta Misra /* some field sizes of ofmt_field_t arrays */ 105dbed73cbSSangeeta Misra #define IPv4_FIELDWIDTH 16 106dbed73cbSSangeeta Misra #define IPv6_FIELDWIDTH 39 107dbed73cbSSangeeta Misra #define ILB_HOSTNAMELEN 20 108dbed73cbSSangeeta Misra #define ILB_STATUSFIELD_LEN 7 109dbed73cbSSangeeta Misra 110dbed73cbSSangeeta Misra typedef struct arg_struct { 111dbed73cbSSangeeta Misra int flags; 112dbed73cbSSangeeta Misra char *o_str; 113dbed73cbSSangeeta Misra ofmt_field_t *o_fields; 114dbed73cbSSangeeta Misra ofmt_handle_t oh; 115dbed73cbSSangeeta Misra } ilbadm_sh_rl_arg_t; 116dbed73cbSSangeeta Misra 117dbed73cbSSangeeta Misra typedef struct ilbadm_rl_exp_arg { 118dbed73cbSSangeeta Misra FILE *fp; 119dbed73cbSSangeeta Misra } ilbadm_rl_exp_arg_t; 120dbed73cbSSangeeta Misra 121dbed73cbSSangeeta Misra typedef struct ilbadm_rl_list_arg { 122dbed73cbSSangeeta Misra ilb_handle_t h; 123dbed73cbSSangeeta Misra ilb_rule_data_t *rd; 124dbed73cbSSangeeta Misra } ilbadm_rl_list_arg_t; 125dbed73cbSSangeeta Misra 126dbed73cbSSangeeta Misra typedef struct ilbadm_rl_srvlist_arg { 127dbed73cbSSangeeta Misra char *sgname; 128dbed73cbSSangeeta Misra ilb_server_data_t *sd; 129dbed73cbSSangeeta Misra ilb_rule_data_t *rd; 130dbed73cbSSangeeta Misra int flags; 131dbed73cbSSangeeta Misra char *o_str; 132dbed73cbSSangeeta Misra ofmt_field_t *o_fields; 133dbed73cbSSangeeta Misra ofmt_handle_t oh; 134dbed73cbSSangeeta Misra } ilbadm_rl_srvlist_arg_t; 135dbed73cbSSangeeta Misra 136dbed73cbSSangeeta Misra static ofmt_cb_t of_algo; 137dbed73cbSSangeeta Misra static ofmt_cb_t of_proto; 138dbed73cbSSangeeta Misra static ofmt_cb_t of_rl_ip; 139dbed73cbSSangeeta Misra static ofmt_cb_t of_rl_mask; 140dbed73cbSSangeeta Misra static ofmt_cb_t of_rport; 141dbed73cbSSangeeta Misra static ofmt_cb_t of_rstatus; 142dbed73cbSSangeeta Misra static ofmt_cb_t of_str; 143dbed73cbSSangeeta Misra static ofmt_cb_t of_time; 144dbed73cbSSangeeta Misra static ofmt_cb_t of_topo; 145dbed73cbSSangeeta Misra static ofmt_cb_t of_rl_srvlist; 146dbed73cbSSangeeta Misra 147dbed73cbSSangeeta Misra static boolean_t of_srv2str(ofmt_arg_t *, char *, uint_t); 148dbed73cbSSangeeta Misra static boolean_t of_port2str(in_port_t, in_port_t, char *, uint_t); 149dbed73cbSSangeeta Misra 150dbed73cbSSangeeta Misra static ofmt_field_t rfields_v4[] = { 151dbed73cbSSangeeta Misra {"RULENAME", ILB_NAMESZ, OF_STR_RNAME, of_str}, 152dbed73cbSSangeeta Misra {"STATUS", ILB_STATUSFIELD_LEN, 0, of_rstatus}, 153dbed73cbSSangeeta Misra {"PORT", 10, OF_PORT, of_rport}, 154dbed73cbSSangeeta Misra {"PROTOCOL", 5, 0, of_proto}, 155dbed73cbSSangeeta Misra {"LBALG", 12, 0, of_algo}, 156dbed73cbSSangeeta Misra {"TYPE", 8, 0, of_topo}, 157dbed73cbSSangeeta Misra {"PROXY-SRC", 2*IPv4_FIELDWIDTH+1, OF_IP_PROXYSRC, of_rl_ip}, 158dbed73cbSSangeeta Misra {"PMASK", 6, OF_IP_STICKYMASK, of_rl_mask}, 159dbed73cbSSangeeta Misra {"HC-NAME", ILB_NAMESZ, OF_STR_HCNAME, of_str}, 160dbed73cbSSangeeta Misra {"HC-PORT", 8, OF_HCPORT, of_rport}, 161dbed73cbSSangeeta Misra {"CONN-DRAIN", 11, OF_T_CONN, of_time}, 162dbed73cbSSangeeta Misra {"NAT-TIMEOUT", 12, OF_T_NAT, of_time}, 163dbed73cbSSangeeta Misra {"PERSIST-TIMEOUT", 16, OF_T_STICKY, of_time}, 164dbed73cbSSangeeta Misra {"SERVERGROUP", ILB_SGNAME_SZ, OF_STR_SGNAME, of_str}, 165dbed73cbSSangeeta Misra {"VIP", IPv4_FIELDWIDTH, OF_IP_VIP, of_rl_ip}, 166dbed73cbSSangeeta Misra {"SERVERS", 20, 0, of_rl_srvlist}, 167dbed73cbSSangeeta Misra {NULL, 0, 0, NULL} 168dbed73cbSSangeeta Misra }; 169dbed73cbSSangeeta Misra 170dbed73cbSSangeeta Misra static ofmt_field_t rfields_v6[] = { 171dbed73cbSSangeeta Misra {"RULENAME", ILB_NAMESZ, OF_STR_RNAME, of_str}, 172dbed73cbSSangeeta Misra {"STATUS", ILB_STATUSFIELD_LEN, 0, of_rstatus}, 173dbed73cbSSangeeta Misra {"PORT", 10, OF_PORT, of_rport}, 174dbed73cbSSangeeta Misra {"PROTOCOL", 5, 0, of_proto}, 175dbed73cbSSangeeta Misra {"LBALG", 12, 0, of_algo}, 176dbed73cbSSangeeta Misra {"TYPE", 8, 0, of_topo}, 177dbed73cbSSangeeta Misra {"PROXY-SRC", IPv6_FIELDWIDTH, OF_IP_PROXYSRC, of_rl_ip}, 178dbed73cbSSangeeta Misra {"PMASK", 6, OF_IP_STICKYMASK, of_rl_mask}, 179dbed73cbSSangeeta Misra {"HC-NAME", ILB_NAMESZ, OF_STR_HCNAME, of_str}, 180dbed73cbSSangeeta Misra {"HC-PORT", 8, OF_HCPORT, of_rport}, 181dbed73cbSSangeeta Misra {"CONN-DRAIN", 11, OF_T_CONN, of_time}, 182dbed73cbSSangeeta Misra {"NAT-TIMEOUT", 12, OF_T_NAT, of_time}, 183dbed73cbSSangeeta Misra {"PERSIST-TIMEOUT", 16, OF_T_STICKY, of_time}, 184dbed73cbSSangeeta Misra {"SERVERGROUP", ILB_SGNAME_SZ, OF_STR_SGNAME, of_str}, 185dbed73cbSSangeeta Misra {"VIP", IPv6_FIELDWIDTH, OF_IP_VIP, of_rl_ip}, 186dbed73cbSSangeeta Misra {"SERVERS", 20, 0, of_rl_srvlist}, 187dbed73cbSSangeeta Misra {NULL, 0, 0, NULL} 188dbed73cbSSangeeta Misra }; 189dbed73cbSSangeeta Misra 190dbed73cbSSangeeta Misra static ofmt_field_t ssfields_v4[] = { 191dbed73cbSSangeeta Misra {"SERVERID", ILB_NAMESZ, OF_SRV_ID, of_srv2str}, 192dbed73cbSSangeeta Misra {"ADDRESS", IPv4_FIELDWIDTH, OF_SRV_ADDR, of_srv2str}, 193dbed73cbSSangeeta Misra {"PORT", 5, OF_SRV_PORT, of_srv2str}, 194dbed73cbSSangeeta Misra {"RULENAME", ILB_NAMESZ, OF_SRV_RNAME, of_srv2str}, 195dbed73cbSSangeeta Misra {"STATUS", ILB_STATUSFIELD_LEN, OF_SRV_STATUS, of_srv2str}, 196dbed73cbSSangeeta Misra {"SERVERGROUP", ILB_SGNAME_SZ, OF_SRV_SGNAME, of_srv2str}, 197dbed73cbSSangeeta Misra {"HOSTNAME", ILB_HOSTNAMELEN, OF_SRV_HOSTNAME, of_srv2str}, 198dbed73cbSSangeeta Misra {NULL, 0, 0, NULL} 199dbed73cbSSangeeta Misra }; 200dbed73cbSSangeeta Misra 201dbed73cbSSangeeta Misra static ofmt_field_t ssfields_v6[] = { 202dbed73cbSSangeeta Misra {"SERVERID", ILB_NAMESZ, OF_SRV_ID, of_srv2str}, 203dbed73cbSSangeeta Misra {"ADDRESS", IPv6_FIELDWIDTH, OF_SRV_ADDR, of_srv2str}, 204dbed73cbSSangeeta Misra {"PORT", 5, OF_SRV_PORT, of_srv2str}, 205dbed73cbSSangeeta Misra {"RULENAME", ILB_NAMESZ, OF_SRV_RNAME, of_srv2str}, 206dbed73cbSSangeeta Misra {"STATUS", ILB_STATUSFIELD_LEN, OF_SRV_STATUS, of_srv2str}, 207dbed73cbSSangeeta Misra {"SERVERGROUP", ILB_SGNAME_SZ, OF_SRV_SGNAME, of_srv2str}, 208dbed73cbSSangeeta Misra {"HOSTNAME", ILB_HOSTNAMELEN, OF_SRV_HOSTNAME, of_srv2str}, 209dbed73cbSSangeeta Misra {NULL, 0, 0, NULL} 210dbed73cbSSangeeta Misra }; 211dbed73cbSSangeeta Misra 212dbed73cbSSangeeta Misra extern int optind, optopt, opterr; 213dbed73cbSSangeeta Misra extern char *optarg; 214dbed73cbSSangeeta Misra 215dbed73cbSSangeeta Misra extern ilbadm_val_type_t algo_types[]; 216dbed73cbSSangeeta Misra extern ilbadm_val_type_t topo_types[]; 217dbed73cbSSangeeta Misra 218dbed73cbSSangeeta Misra static char * 219dbed73cbSSangeeta Misra i_key_to_opt(ilbadm_key_name_t *n, ilbadm_key_code_t k) 220dbed73cbSSangeeta Misra { 221dbed73cbSSangeeta Misra int i; 222dbed73cbSSangeeta Misra 223dbed73cbSSangeeta Misra for (i = 0; n[i].k_key != ILB_KEY_BAD; i++) 224dbed73cbSSangeeta Misra if (n[i].k_key == k) 225dbed73cbSSangeeta Misra break; 226dbed73cbSSangeeta Misra 227dbed73cbSSangeeta Misra return (n[i].k_name); 228dbed73cbSSangeeta Misra } 229dbed73cbSSangeeta Misra 230dbed73cbSSangeeta Misra char * 231dbed73cbSSangeeta Misra ilbadm_key_to_opt(ilbadm_key_code_t k) 232dbed73cbSSangeeta Misra { 233dbed73cbSSangeeta Misra char *name; 234dbed73cbSSangeeta Misra int i; 235dbed73cbSSangeeta Misra 236dbed73cbSSangeeta Misra for (i = 0; all_keys[i] != NULL; i++) { 237dbed73cbSSangeeta Misra name = i_key_to_opt(all_keys[i], k); 238dbed73cbSSangeeta Misra if (*name != '\0') 239dbed73cbSSangeeta Misra return (name); 240dbed73cbSSangeeta Misra } 241dbed73cbSSangeeta Misra 242dbed73cbSSangeeta Misra return (NULL); 243dbed73cbSSangeeta Misra } 244dbed73cbSSangeeta Misra 245dbed73cbSSangeeta Misra /* 246dbed73cbSSangeeta Misra * ports are in HOST byte order 247dbed73cbSSangeeta Misra */ 248dbed73cbSSangeeta Misra static void 249dbed73cbSSangeeta Misra ports2str(short port1, short port2, char *buf, const int sz) 250dbed73cbSSangeeta Misra { 251dbed73cbSSangeeta Misra if (port2 <= port1) 252dbed73cbSSangeeta Misra (void) snprintf(buf, sz, "port=%d", port1); 253dbed73cbSSangeeta Misra else 254dbed73cbSSangeeta Misra (void) snprintf(buf, sz, "port=%d-%d", port1, port2); 255dbed73cbSSangeeta Misra } 256dbed73cbSSangeeta Misra 257dbed73cbSSangeeta Misra static void 258dbed73cbSSangeeta Misra proto2str(short proto, char *buf, int sz) 259dbed73cbSSangeeta Misra { 260dbed73cbSSangeeta Misra struct protoent *pe; 261dbed73cbSSangeeta Misra 262dbed73cbSSangeeta Misra pe = getprotobynumber((int)proto); 263dbed73cbSSangeeta Misra if (pe != NULL) 264dbed73cbSSangeeta Misra (void) snprintf(buf, sz, "protocol=%s", pe->p_name); 265dbed73cbSSangeeta Misra else 266dbed73cbSSangeeta Misra (void) sprintf(buf, "(bad proto %d)", proto); 267dbed73cbSSangeeta Misra } 268dbed73cbSSangeeta Misra 269dbed73cbSSangeeta Misra static void 270dbed73cbSSangeeta Misra algo2str(ilb_algo_t algo, char *buf, int sz) 271dbed73cbSSangeeta Misra { 272dbed73cbSSangeeta Misra char *s = i_str_from_val((int)algo, &algo_types[0]); 273dbed73cbSSangeeta Misra 274dbed73cbSSangeeta Misra (void) snprintf(buf, sz, "lbalg=%s", (s && *s) ? s : "(bad algo)"); 275dbed73cbSSangeeta Misra } 276dbed73cbSSangeeta Misra 277dbed73cbSSangeeta Misra static int 278dbed73cbSSangeeta Misra algo2bare_str(ilb_algo_t algo, char *buf, int sz) 279dbed73cbSSangeeta Misra { 280dbed73cbSSangeeta Misra char *s = i_str_from_val((int)algo, &algo_types[0]); 281dbed73cbSSangeeta Misra 282dbed73cbSSangeeta Misra return (snprintf(buf, sz, "%s", (s && *s) ? s : "")); 283dbed73cbSSangeeta Misra } 284dbed73cbSSangeeta Misra 285dbed73cbSSangeeta Misra static void 286dbed73cbSSangeeta Misra topo2str(ilb_topo_t topo, char *buf, int sz) 287dbed73cbSSangeeta Misra { 288dbed73cbSSangeeta Misra char *s = i_str_from_val((int)topo, &topo_types[0]); 289dbed73cbSSangeeta Misra 290dbed73cbSSangeeta Misra (void) snprintf(buf, sz, "type=%s", (s && *s) ? s : "(bad type)"); 291dbed73cbSSangeeta Misra } 292dbed73cbSSangeeta Misra 293dbed73cbSSangeeta Misra static int 294dbed73cbSSangeeta Misra topo2bare_str(ilb_topo_t topo, char *buf, int sz) 295dbed73cbSSangeeta Misra { 296dbed73cbSSangeeta Misra char *s = i_str_from_val((int)topo, &topo_types[0]); 297dbed73cbSSangeeta Misra 298dbed73cbSSangeeta Misra return (snprintf(buf, sz, "%s", (s && *s) ? s : "")); 299dbed73cbSSangeeta Misra } 300dbed73cbSSangeeta Misra 301dbed73cbSSangeeta Misra static boolean_t 302dbed73cbSSangeeta Misra of_str(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 303dbed73cbSSangeeta Misra { 304dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 305dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 306dbed73cbSSangeeta Misra 307dbed73cbSSangeeta Misra switch (of_arg->ofmt_id) { 308dbed73cbSSangeeta Misra case OF_STR_RNAME: 309dbed73cbSSangeeta Misra (void) strlcpy(buf, rd->r_name, bufsize); 310dbed73cbSSangeeta Misra break; 311dbed73cbSSangeeta Misra case OF_STR_SGNAME: 312dbed73cbSSangeeta Misra (void) strlcpy(buf, rd->r_sgname, bufsize); 313dbed73cbSSangeeta Misra break; 314dbed73cbSSangeeta Misra case OF_STR_HCNAME: 315dbed73cbSSangeeta Misra if (rd->r_hcname != NULL && *(rd->r_hcname) != '\0') 316dbed73cbSSangeeta Misra (void) strlcpy(buf, rd->r_hcname, bufsize); 317dbed73cbSSangeeta Misra break; 318dbed73cbSSangeeta Misra } 319dbed73cbSSangeeta Misra return (B_TRUE); 320dbed73cbSSangeeta Misra } 321dbed73cbSSangeeta Misra 322dbed73cbSSangeeta Misra /* ARGSUSED */ 323dbed73cbSSangeeta Misra static boolean_t 324dbed73cbSSangeeta Misra of_proto(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 325dbed73cbSSangeeta Misra { 326dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 327dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 328dbed73cbSSangeeta Misra 329dbed73cbSSangeeta Misra if (rd->r_proto == IPPROTO_TCP) 330dbed73cbSSangeeta Misra (void) strlcpy(buf, "TCP", bufsize); 331dbed73cbSSangeeta Misra else if (rd->r_proto == IPPROTO_UDP) 332dbed73cbSSangeeta Misra (void) strlcpy(buf, "UDP", bufsize); 333dbed73cbSSangeeta Misra else 334dbed73cbSSangeeta Misra return (B_FALSE); 335dbed73cbSSangeeta Misra return (B_TRUE); 336dbed73cbSSangeeta Misra } 337dbed73cbSSangeeta Misra 338dbed73cbSSangeeta Misra static boolean_t 339dbed73cbSSangeeta Misra of_rl_ip(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 340dbed73cbSSangeeta Misra { 341dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 342dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 343dbed73cbSSangeeta Misra ilb_ip_addr_t *ip = NULL, *ip2 = NULL; 344dbed73cbSSangeeta Misra 345dbed73cbSSangeeta Misra switch (of_arg->ofmt_id) { 346dbed73cbSSangeeta Misra case OF_IP_VIP: 347dbed73cbSSangeeta Misra ip = &rd->r_vip; 348dbed73cbSSangeeta Misra break; 349dbed73cbSSangeeta Misra case OF_IP_PROXYSRC: 350dbed73cbSSangeeta Misra ip = &rd->r_nat_src_start; 351dbed73cbSSangeeta Misra ip2 = &rd->r_nat_src_end; 352dbed73cbSSangeeta Misra break; 353dbed73cbSSangeeta Misra case OF_IP_STICKYMASK: 354dbed73cbSSangeeta Misra ip = &rd->r_stickymask; 355dbed73cbSSangeeta Misra break; 356dbed73cbSSangeeta Misra } 357dbed73cbSSangeeta Misra 358dbed73cbSSangeeta Misra /* only print something valid */ 359dbed73cbSSangeeta Misra if (ip != NULL && (ip->ia_af == AF_INET || ip->ia_af == AF_INET6)) 360dbed73cbSSangeeta Misra ip2str(ip, buf, bufsize, V6_ADDRONLY); 361dbed73cbSSangeeta Misra if (ip2 != NULL && (ip2->ia_af == AF_INET || ip2->ia_af == AF_INET6) && 362dbed73cbSSangeeta Misra buf[0] != '\0') { 363dbed73cbSSangeeta Misra int sl = strlen(buf); 364dbed73cbSSangeeta Misra 365dbed73cbSSangeeta Misra buf += sl; bufsize -= sl; 366dbed73cbSSangeeta Misra *buf++ = '-'; bufsize--; 367dbed73cbSSangeeta Misra ip2str(ip2, buf, bufsize, V6_ADDRONLY); 368dbed73cbSSangeeta Misra } 369dbed73cbSSangeeta Misra 370dbed73cbSSangeeta Misra return (B_TRUE); 371dbed73cbSSangeeta Misra } 372dbed73cbSSangeeta Misra 373dbed73cbSSangeeta Misra static boolean_t 374dbed73cbSSangeeta Misra of_rl_mask(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 375dbed73cbSSangeeta Misra { 376dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 377dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 378dbed73cbSSangeeta Misra ilb_ip_addr_t *ip = NULL; 379dbed73cbSSangeeta Misra 380dbed73cbSSangeeta Misra assert(of_arg->ofmt_id == OF_IP_STICKYMASK); 381dbed73cbSSangeeta Misra if (!(rd->r_flags & ILB_FLAGS_RULE_STICKY)) 382dbed73cbSSangeeta Misra return (B_TRUE); 383dbed73cbSSangeeta Misra ip = &rd->r_stickymask; 384dbed73cbSSangeeta Misra 385dbed73cbSSangeeta Misra (void) snprintf(buf, bufsize, "/%d", ilbadm_mask_to_prefixlen(ip)); 386dbed73cbSSangeeta Misra return (B_TRUE); 387dbed73cbSSangeeta Misra } 388dbed73cbSSangeeta Misra 389dbed73cbSSangeeta Misra static void 390dbed73cbSSangeeta Misra hcport_print(ilb_rule_data_t *rd, char *buf, uint_t bufsize) 391dbed73cbSSangeeta Misra { 392dbed73cbSSangeeta Misra if (rd->r_hcport != 0) 393dbed73cbSSangeeta Misra (void) snprintf(buf, bufsize, "%d", ntohs(rd->r_hcport)); 394dbed73cbSSangeeta Misra else if (rd->r_hcpflag == ILB_HCI_PROBE_ANY) 395dbed73cbSSangeeta Misra (void) snprintf(buf, bufsize, "ANY"); 396dbed73cbSSangeeta Misra else 397dbed73cbSSangeeta Misra buf[0] = '\0'; 398dbed73cbSSangeeta Misra } 399dbed73cbSSangeeta Misra static boolean_t 400dbed73cbSSangeeta Misra of_rport(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 401dbed73cbSSangeeta Misra { 402dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 403dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 404dbed73cbSSangeeta Misra 405dbed73cbSSangeeta Misra if (of_arg->ofmt_id == OF_PORT) 406dbed73cbSSangeeta Misra return (of_port2str(rd->r_minport, rd->r_maxport, buf, 407dbed73cbSSangeeta Misra bufsize)); 408dbed73cbSSangeeta Misra 409dbed73cbSSangeeta Misra /* only print a hcport if there's a hc name as well */ 410dbed73cbSSangeeta Misra if (of_arg->ofmt_id == OF_HCPORT && rd->r_hcname[0] != '\0') 411dbed73cbSSangeeta Misra hcport_print(rd, buf, bufsize); 412dbed73cbSSangeeta Misra 413dbed73cbSSangeeta Misra return (B_TRUE); 414dbed73cbSSangeeta Misra } 415dbed73cbSSangeeta Misra 416dbed73cbSSangeeta Misra /* ARGSUSED */ 417dbed73cbSSangeeta Misra static boolean_t 418dbed73cbSSangeeta Misra of_rstatus(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 419dbed73cbSSangeeta Misra { 420dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 421dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 422dbed73cbSSangeeta Misra 423dbed73cbSSangeeta Misra if ((rd->r_flags & ILB_FLAGS_RULE_ENABLED) == ILB_FLAGS_RULE_ENABLED) 424dbed73cbSSangeeta Misra buf[0] = 'E'; 425dbed73cbSSangeeta Misra else 426dbed73cbSSangeeta Misra buf[0] = 'D'; 427dbed73cbSSangeeta Misra buf[1] = '\0'; 428dbed73cbSSangeeta Misra return (B_TRUE); 429dbed73cbSSangeeta Misra } 430dbed73cbSSangeeta Misra 431dbed73cbSSangeeta Misra static boolean_t 432dbed73cbSSangeeta Misra of_algo(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 433dbed73cbSSangeeta Misra { 434dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 435dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 436dbed73cbSSangeeta Misra 437dbed73cbSSangeeta Misra if (algo2bare_str(rd->r_algo, buf, bufsize) == 0) 438dbed73cbSSangeeta Misra return (B_FALSE); 439dbed73cbSSangeeta Misra return (B_TRUE); 440dbed73cbSSangeeta Misra } 441dbed73cbSSangeeta Misra 442dbed73cbSSangeeta Misra static boolean_t 443dbed73cbSSangeeta Misra of_topo(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 444dbed73cbSSangeeta Misra { 445dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 446dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 447dbed73cbSSangeeta Misra 448dbed73cbSSangeeta Misra if (topo2bare_str(rd->r_topo, buf, bufsize) == 0) 449dbed73cbSSangeeta Misra return (B_FALSE); 450dbed73cbSSangeeta Misra return (B_TRUE); 451dbed73cbSSangeeta Misra } 452dbed73cbSSangeeta Misra 453dbed73cbSSangeeta Misra static boolean_t 454dbed73cbSSangeeta Misra of_time(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 455dbed73cbSSangeeta Misra { 456dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 457dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 458dbed73cbSSangeeta Misra 459dbed73cbSSangeeta Misra switch (of_arg->ofmt_id) { 460dbed73cbSSangeeta Misra case OF_T_CONN: 461dbed73cbSSangeeta Misra (void) snprintf(buf, bufsize, "%u", rd->r_conndrain); 462dbed73cbSSangeeta Misra break; 463dbed73cbSSangeeta Misra case OF_T_NAT: 464dbed73cbSSangeeta Misra (void) snprintf(buf, bufsize, "%u", rd->r_nat_timeout); 465dbed73cbSSangeeta Misra break; 466dbed73cbSSangeeta Misra case OF_T_STICKY: 467dbed73cbSSangeeta Misra (void) snprintf(buf, bufsize, "%u", rd->r_sticky_timeout); 468dbed73cbSSangeeta Misra break; 469dbed73cbSSangeeta Misra } 470dbed73cbSSangeeta Misra return (B_TRUE); 471dbed73cbSSangeeta Misra } 472dbed73cbSSangeeta Misra 473dbed73cbSSangeeta Misra typedef struct rl_showlist_arg { 474dbed73cbSSangeeta Misra char *buf; 475dbed73cbSSangeeta Misra uint_t bufsize; 476dbed73cbSSangeeta Misra } rl_showlist_arg_t; 477dbed73cbSSangeeta Misra 478dbed73cbSSangeeta Misra /* ARGSUSED */ 479dbed73cbSSangeeta Misra /* called by ilb_walk_servers(), cannot get rid of unused args */ 480dbed73cbSSangeeta Misra static ilb_status_t 481dbed73cbSSangeeta Misra srv2srvID(ilb_handle_t h, ilb_server_data_t *sd, const char *sgname, void *arg) 482dbed73cbSSangeeta Misra { 483dbed73cbSSangeeta Misra rl_showlist_arg_t *sla = (rl_showlist_arg_t *)arg; 484dbed73cbSSangeeta Misra int len; 485dbed73cbSSangeeta Misra 486dbed73cbSSangeeta Misra (void) snprintf(sla->buf, sla->bufsize, "%s,", sd->sd_srvID); 487dbed73cbSSangeeta Misra len = strlen(sd->sd_srvID) + 1; 488dbed73cbSSangeeta Misra sla->buf += len; 489dbed73cbSSangeeta Misra sla->bufsize -= len; 490dbed73cbSSangeeta Misra 491dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 492dbed73cbSSangeeta Misra } 493dbed73cbSSangeeta Misra 494dbed73cbSSangeeta Misra static boolean_t 495dbed73cbSSangeeta Misra of_rl_srvlist(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 496dbed73cbSSangeeta Misra { 497dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t *ra = (ilbadm_rl_list_arg_t *)of_arg->ofmt_cbarg; 498dbed73cbSSangeeta Misra ilb_rule_data_t *rd = (ilb_rule_data_t *)ra->rd; 499dbed73cbSSangeeta Misra rl_showlist_arg_t sla; 500dbed73cbSSangeeta Misra 501dbed73cbSSangeeta Misra sla.buf = buf; 502dbed73cbSSangeeta Misra sla.bufsize = bufsize; 503dbed73cbSSangeeta Misra 504dbed73cbSSangeeta Misra (void) ilb_walk_servers(ra->h, srv2srvID, rd->r_sgname, 505dbed73cbSSangeeta Misra (void *)&sla); 506dbed73cbSSangeeta Misra /* we're trailing a ',' which we need to remove */ 507dbed73cbSSangeeta Misra *--sla.buf = '\0'; 508dbed73cbSSangeeta Misra 509dbed73cbSSangeeta Misra return (B_TRUE); 510dbed73cbSSangeeta Misra } 511dbed73cbSSangeeta Misra 512dbed73cbSSangeeta Misra #define RMAXCOLS 120 /* enough? */ 513dbed73cbSSangeeta Misra #define SERVER_WIDTH (ILB_NAMESZ+1) /* 1st guess */ 514dbed73cbSSangeeta Misra 515dbed73cbSSangeeta Misra static boolean_t 516dbed73cbSSangeeta Misra of_port2str(in_port_t minport, in_port_t maxport, char *buf, uint_t bufsize) 517dbed73cbSSangeeta Misra { 518dbed73cbSSangeeta Misra in_port_t h_min, h_max; 519dbed73cbSSangeeta Misra int len; 520dbed73cbSSangeeta Misra 521dbed73cbSSangeeta Misra h_min = ntohs(minport); 522dbed73cbSSangeeta Misra h_max = ntohs(maxport); 523dbed73cbSSangeeta Misra 524dbed73cbSSangeeta Misra if (h_min == 0) 525dbed73cbSSangeeta Misra return (B_FALSE); /* print "unspec" == "all ports" */ 526dbed73cbSSangeeta Misra 527dbed73cbSSangeeta Misra len = snprintf(buf, bufsize, "%d", h_min); 528dbed73cbSSangeeta Misra if (h_max > h_min) 529dbed73cbSSangeeta Misra (void) snprintf(buf + len, bufsize - len, "-%d", h_max); 530dbed73cbSSangeeta Misra return (B_TRUE); 531dbed73cbSSangeeta Misra } 532dbed73cbSSangeeta Misra 533dbed73cbSSangeeta Misra static ilbadm_status_t 534dbed73cbSSangeeta Misra ip2hostname(ilb_ip_addr_t *ip, char *buf, uint_t bufsize) 535dbed73cbSSangeeta Misra { 536dbed73cbSSangeeta Misra int ret; 537dbed73cbSSangeeta Misra struct hostent *he; 538dbed73cbSSangeeta Misra 539dbed73cbSSangeeta Misra switch (ip->ia_af) { 540dbed73cbSSangeeta Misra case AF_INET: 541dbed73cbSSangeeta Misra he = getipnodebyaddr((char *)&ip->ia_v4, sizeof (ip->ia_v4), 542dbed73cbSSangeeta Misra ip->ia_af, &ret); 543dbed73cbSSangeeta Misra break; 544dbed73cbSSangeeta Misra case AF_INET6: 545dbed73cbSSangeeta Misra he = getipnodebyaddr((char *)&ip->ia_v6, sizeof (ip->ia_v6), 546dbed73cbSSangeeta Misra ip->ia_af, &ret); 547dbed73cbSSangeeta Misra break; 548dbed73cbSSangeeta Misra default: return (ILBADM_INVAL_AF); 549dbed73cbSSangeeta Misra } 550dbed73cbSSangeeta Misra 551dbed73cbSSangeeta Misra /* if we can't resolve this, just return an empty name */ 552dbed73cbSSangeeta Misra if (he == NULL) 553dbed73cbSSangeeta Misra buf[0] = '\0'; 554dbed73cbSSangeeta Misra else 555dbed73cbSSangeeta Misra (void) strlcpy(buf, he->h_name, bufsize); 556dbed73cbSSangeeta Misra 557dbed73cbSSangeeta Misra return (ILBADM_OK); 558dbed73cbSSangeeta Misra } 559dbed73cbSSangeeta Misra 560dbed73cbSSangeeta Misra /* ARGSUSED */ 561dbed73cbSSangeeta Misra /* 562dbed73cbSSangeeta Misra * Since this function is used by libilb routine ilb_walk_rules() 563dbed73cbSSangeeta Misra * it must return libilb errors 564dbed73cbSSangeeta Misra */ 565dbed73cbSSangeeta Misra static ilb_status_t 566dbed73cbSSangeeta Misra ilbadm_show_onerule(ilb_handle_t h, ilb_rule_data_t *rd, void *arg) 567dbed73cbSSangeeta Misra { 568dbed73cbSSangeeta Misra ilbadm_sh_rl_arg_t *larg = (ilbadm_sh_rl_arg_t *)arg; 569dbed73cbSSangeeta Misra ofmt_status_t oerr; 570dbed73cbSSangeeta Misra int oflags = 0; 571dbed73cbSSangeeta Misra int ocols = RMAXCOLS; 572dbed73cbSSangeeta Misra ilbadm_rl_list_arg_t ra; 573dbed73cbSSangeeta Misra static ofmt_handle_t oh = (ofmt_handle_t)NULL; 574dbed73cbSSangeeta Misra ofmt_field_t *fields; 575dbed73cbSSangeeta Misra boolean_t r_enabled = rd->r_flags & ILB_FLAGS_RULE_ENABLED; 576dbed73cbSSangeeta Misra 577dbed73cbSSangeeta Misra if (larg->o_str == NULL) { 578dbed73cbSSangeeta Misra ilbadm_err(gettext("internal error")); 579dbed73cbSSangeeta Misra return (ILB_STATUS_GENERIC); 580dbed73cbSSangeeta Misra } 581dbed73cbSSangeeta Misra 582dbed73cbSSangeeta Misra /* 583dbed73cbSSangeeta Misra * only print rules (enabled/dis-) we're asked to 584dbed73cbSSangeeta Misra * note: both LIST_**ABLED flags can be set at the same time, 585dbed73cbSSangeeta Misra * whereas a rule has one state only. therefore the complicated 586dbed73cbSSangeeta Misra * statement. 587dbed73cbSSangeeta Misra */ 588dbed73cbSSangeeta Misra if (!((r_enabled && (larg->flags & ILBADM_LIST_ENABLED)) || 589dbed73cbSSangeeta Misra (!r_enabled && (larg->flags & ILBADM_LIST_DISABLED)))) 590dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 591dbed73cbSSangeeta Misra 592dbed73cbSSangeeta Misra if (larg->flags & ILBADM_LIST_PARSE) 593dbed73cbSSangeeta Misra oflags |= OFMT_PARSABLE; 594dbed73cbSSangeeta Misra 595dbed73cbSSangeeta Misra if (larg->flags & ILBADM_LIST_FULL) 596dbed73cbSSangeeta Misra oflags |= OFMT_MULTILINE; 597dbed73cbSSangeeta Misra 598dbed73cbSSangeeta Misra bzero(&ra, sizeof (ra)); 599dbed73cbSSangeeta Misra ra.rd = rd; 600dbed73cbSSangeeta Misra ra.h = h; 601dbed73cbSSangeeta Misra 602dbed73cbSSangeeta Misra if (oh == NULL) { 603dbed73cbSSangeeta Misra if (rd->r_vip.ia_af == AF_INET) 604dbed73cbSSangeeta Misra fields = rfields_v4; 605dbed73cbSSangeeta Misra else 606dbed73cbSSangeeta Misra fields = rfields_v6; 607dbed73cbSSangeeta Misra 608dbed73cbSSangeeta Misra oerr = ofmt_open(larg->o_str, fields, oflags, ocols, &oh); 609dbed73cbSSangeeta Misra if (oerr != OFMT_SUCCESS) { 610dbed73cbSSangeeta Misra char e[80]; 611dbed73cbSSangeeta Misra 612dbed73cbSSangeeta Misra ilbadm_err(gettext("ofmt_open failed: %s"), 613dbed73cbSSangeeta Misra ofmt_strerror(oh, oerr, e, sizeof (e))); 614dbed73cbSSangeeta Misra return (ILB_STATUS_GENERIC); 615dbed73cbSSangeeta Misra } 616dbed73cbSSangeeta Misra } 617dbed73cbSSangeeta Misra 618dbed73cbSSangeeta Misra ofmt_print(oh, &ra); 619dbed73cbSSangeeta Misra 620dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 621dbed73cbSSangeeta Misra } 622dbed73cbSSangeeta Misra 623dbed73cbSSangeeta Misra static char *full_list_rule_hdrs = 624dbed73cbSSangeeta Misra "RULENAME,STATUS,PORT,PROTOCOL,LBALG,TYPE,PROXY-SRC,PMASK," 625dbed73cbSSangeeta Misra "HC-NAME,HC-PORT,CONN-DRAIN,NAT-TIMEOUT," 626dbed73cbSSangeeta Misra "PERSIST-TIMEOUT,SERVERGROUP,VIP,SERVERS"; 627dbed73cbSSangeeta Misra static char *def_list_rule_hdrs = 628dbed73cbSSangeeta Misra "RULENAME,STATUS,LBALG,TYPE,PROTOCOL,VIP,PORT"; 629dbed73cbSSangeeta Misra 630dbed73cbSSangeeta Misra /* ARGSUSED */ 631dbed73cbSSangeeta Misra ilbadm_status_t 632dbed73cbSSangeeta Misra ilbadm_show_rules(int argc, char *argv[]) 633dbed73cbSSangeeta Misra { 634dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE; 635dbed73cbSSangeeta Misra int c; 636dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK; 637dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK; 638dbed73cbSSangeeta Misra boolean_t o_opt = B_FALSE, p_opt = B_FALSE; 639dbed73cbSSangeeta Misra boolean_t f_opt = B_FALSE; 640dbed73cbSSangeeta Misra ilbadm_sh_rl_arg_t larg = {0, NULL, NULL, NULL}; 641dbed73cbSSangeeta Misra 642dbed73cbSSangeeta Misra larg.flags = ILBADM_LIST_ENABLED | ILBADM_LIST_DISABLED; 643dbed73cbSSangeeta Misra while ((c = getopt(argc, argv, ":fpedo:")) != -1) { 644dbed73cbSSangeeta Misra switch ((char)c) { 645dbed73cbSSangeeta Misra case 'f': larg.flags |= ILBADM_LIST_FULL; 646dbed73cbSSangeeta Misra larg.o_str = full_list_rule_hdrs; 647dbed73cbSSangeeta Misra f_opt = B_TRUE; 648dbed73cbSSangeeta Misra break; 649dbed73cbSSangeeta Misra case 'p': larg.flags |= ILBADM_LIST_PARSE; 650dbed73cbSSangeeta Misra p_opt = B_TRUE; 651dbed73cbSSangeeta Misra break; 652dbed73cbSSangeeta Misra case 'o': larg.o_str = optarg; 653dbed73cbSSangeeta Misra o_opt = B_TRUE; 654dbed73cbSSangeeta Misra break; 655dbed73cbSSangeeta Misra /* -e and -d may be repeated - make sure the last one wins */ 656dbed73cbSSangeeta Misra case 'e': larg.flags &= ILBADM_LIST_NODISABLED; 657dbed73cbSSangeeta Misra larg.flags |= ILBADM_LIST_ENABLED; 658dbed73cbSSangeeta Misra break; 659dbed73cbSSangeeta Misra case 'd': larg.flags &= ILBADM_LIST_NOENABLED; 660dbed73cbSSangeeta Misra larg.flags |= ILBADM_LIST_DISABLED; 661dbed73cbSSangeeta Misra break; 662dbed73cbSSangeeta Misra case ':': ilbadm_err(gettext("missing option argument for %c"), 663dbed73cbSSangeeta Misra (char)optopt); 664dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 665dbed73cbSSangeeta Misra goto out; 666dbed73cbSSangeeta Misra case '?': 667dbed73cbSSangeeta Misra default: 668dbed73cbSSangeeta Misra unknown_opt(argv, optind-1); 669dbed73cbSSangeeta Misra /* not reached */ 670dbed73cbSSangeeta Misra break; 671dbed73cbSSangeeta Misra } 672dbed73cbSSangeeta Misra } 673dbed73cbSSangeeta Misra 674dbed73cbSSangeeta Misra if (f_opt && o_opt) { 675dbed73cbSSangeeta Misra ilbadm_err(gettext("options -o and -f are mutually" 676dbed73cbSSangeeta Misra " exclusive")); 677dbed73cbSSangeeta Misra exit(1); 678dbed73cbSSangeeta Misra } 679dbed73cbSSangeeta Misra 680dbed73cbSSangeeta Misra if (p_opt && !o_opt) { 681dbed73cbSSangeeta Misra ilbadm_err(gettext("option -p requires -o")); 682dbed73cbSSangeeta Misra exit(1); 683dbed73cbSSangeeta Misra } 684dbed73cbSSangeeta Misra 685dbed73cbSSangeeta Misra if (p_opt && larg.o_str != NULL && 686dbed73cbSSangeeta Misra (strcasecmp(larg.o_str, "all") == 0)) { 687dbed73cbSSangeeta Misra ilbadm_err(gettext("option -p requires explicit field" 688dbed73cbSSangeeta Misra " names for -o")); 689dbed73cbSSangeeta Misra exit(1); 690dbed73cbSSangeeta Misra } 691dbed73cbSSangeeta Misra 692dbed73cbSSangeeta Misra /* no -o option, so we use std. fields */ 693dbed73cbSSangeeta Misra if (!o_opt && !f_opt) 694dbed73cbSSangeeta Misra larg.o_str = def_list_rule_hdrs; 695dbed73cbSSangeeta Misra 696dbed73cbSSangeeta Misra rclib = ilb_open(&h); 697dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) 698dbed73cbSSangeeta Misra goto out; 699dbed73cbSSangeeta Misra 700dbed73cbSSangeeta Misra if (optind >= argc) { 701dbed73cbSSangeeta Misra rclib = ilb_walk_rules(h, ilbadm_show_onerule, NULL, 702dbed73cbSSangeeta Misra (void*)&larg); 703dbed73cbSSangeeta Misra } else { 704dbed73cbSSangeeta Misra while (optind < argc) { 705dbed73cbSSangeeta Misra rclib = ilb_walk_rules(h, ilbadm_show_onerule, 706dbed73cbSSangeeta Misra argv[optind++], (void*)&larg); 707dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) 708dbed73cbSSangeeta Misra break; 709dbed73cbSSangeeta Misra } 710dbed73cbSSangeeta Misra } 711dbed73cbSSangeeta Misra out: 712dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE) 713dbed73cbSSangeeta Misra (void) ilb_close(h); 714dbed73cbSSangeeta Misra 715dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) { 716dbed73cbSSangeeta Misra /* 717dbed73cbSSangeeta Misra * The show function returns ILB_STATUS_GENERIC after printing 718dbed73cbSSangeeta Misra * out an error message. So we don't need to print it again. 719dbed73cbSSangeeta Misra */ 720dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_GENERIC) 721dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib)); 722dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 723dbed73cbSSangeeta Misra } 724dbed73cbSSangeeta Misra return (rc); 725dbed73cbSSangeeta Misra } 726dbed73cbSSangeeta Misra 727dbed73cbSSangeeta Misra static boolean_t 728dbed73cbSSangeeta Misra of_srv2str(ofmt_arg_t *of_arg, char *buf, uint_t bufsize) 729dbed73cbSSangeeta Misra { 730dbed73cbSSangeeta Misra ilbadm_rl_srvlist_arg_t *larg = 731dbed73cbSSangeeta Misra (ilbadm_rl_srvlist_arg_t *)of_arg->ofmt_cbarg; 732dbed73cbSSangeeta Misra ilb_server_data_t *sd = larg->sd; 733dbed73cbSSangeeta Misra uint_t op = of_arg->ofmt_id; 734dbed73cbSSangeeta Misra boolean_t ret = B_TRUE; 735dbed73cbSSangeeta Misra ilbadm_status_t rc; 736dbed73cbSSangeeta Misra 737dbed73cbSSangeeta Misra if (sd == NULL) 738dbed73cbSSangeeta Misra return (B_FALSE); 739dbed73cbSSangeeta Misra 740dbed73cbSSangeeta Misra switch (op) { 741dbed73cbSSangeeta Misra case OF_SRV_ID: 742dbed73cbSSangeeta Misra (void) strlcpy(buf, sd->sd_srvID, bufsize); 743dbed73cbSSangeeta Misra break; 744dbed73cbSSangeeta Misra case OF_SRV_STATUS: 745dbed73cbSSangeeta Misra if (ILB_IS_SRV_ENABLED(sd->sd_flags)) 746dbed73cbSSangeeta Misra buf[0] = 'E'; 747dbed73cbSSangeeta Misra else 748dbed73cbSSangeeta Misra buf[0] = 'D'; 749dbed73cbSSangeeta Misra buf[1] = '\0'; 750dbed73cbSSangeeta Misra break; 751dbed73cbSSangeeta Misra case OF_SRV_RNAME: 752dbed73cbSSangeeta Misra (void) strlcpy(buf, larg->rd->r_name, bufsize); 753dbed73cbSSangeeta Misra break; 754dbed73cbSSangeeta Misra case OF_SRV_SGNAME: 755dbed73cbSSangeeta Misra (void) strlcpy(buf, larg->sgname, bufsize); 756dbed73cbSSangeeta Misra break; 757dbed73cbSSangeeta Misra case OF_SRV_HOSTNAME: 758dbed73cbSSangeeta Misra rc = ip2hostname(&sd->sd_addr, buf, bufsize); 759dbed73cbSSangeeta Misra if (rc != ILBADM_OK) { 760dbed73cbSSangeeta Misra buf[0] = '\0'; 761dbed73cbSSangeeta Misra ret = B_FALSE; 762dbed73cbSSangeeta Misra } 763dbed73cbSSangeeta Misra break; 764dbed73cbSSangeeta Misra case OF_SRV_PORT: 765dbed73cbSSangeeta Misra ret = of_port2str(sd->sd_minport, sd->sd_maxport, 766dbed73cbSSangeeta Misra buf, bufsize); 767dbed73cbSSangeeta Misra break; 768dbed73cbSSangeeta Misra case OF_SRV_ADDR: 769dbed73cbSSangeeta Misra ip2str(&sd->sd_addr, buf, bufsize, V6_ADDRONLY); 770dbed73cbSSangeeta Misra break; 771dbed73cbSSangeeta Misra } 772dbed73cbSSangeeta Misra 773dbed73cbSSangeeta Misra return (ret); 774dbed73cbSSangeeta Misra } 775dbed73cbSSangeeta Misra 776dbed73cbSSangeeta Misra /* ARGSUSED */ 777dbed73cbSSangeeta Misra static ilb_status_t 778dbed73cbSSangeeta Misra i_show_rl_srv(ilb_handle_t h, ilb_server_data_t *sd, const char *sgname, 779dbed73cbSSangeeta Misra void *arg) 780dbed73cbSSangeeta Misra { 781dbed73cbSSangeeta Misra ilbadm_rl_srvlist_arg_t *larg = (ilbadm_rl_srvlist_arg_t *)arg; 782dbed73cbSSangeeta Misra 783dbed73cbSSangeeta Misra larg->sd = sd; 784dbed73cbSSangeeta Misra ofmt_print(larg->oh, larg); 785dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 786dbed73cbSSangeeta Misra } 787dbed73cbSSangeeta Misra 788dbed73cbSSangeeta Misra /* ARGSUSED */ 789dbed73cbSSangeeta Misra /* 790dbed73cbSSangeeta Misra * Since this function is used by libilb routine ilb_walk_rules() 791dbed73cbSSangeeta Misra * it must return libilb errors 792dbed73cbSSangeeta Misra */ 793dbed73cbSSangeeta Misra ilb_status_t 794dbed73cbSSangeeta Misra ilbadm_show_rl_servers(ilb_handle_t h, ilb_rule_data_t *rd, void *arg) 795dbed73cbSSangeeta Misra { 796dbed73cbSSangeeta Misra ofmt_status_t oerr; 797dbed73cbSSangeeta Misra int oflags = 0; 798dbed73cbSSangeeta Misra int ocols = RMAXCOLS; 799dbed73cbSSangeeta Misra ofmt_field_t *fields; 800dbed73cbSSangeeta Misra static ofmt_handle_t oh = (ofmt_handle_t)NULL; 801dbed73cbSSangeeta Misra ilbadm_rl_srvlist_arg_t *larg = (ilbadm_rl_srvlist_arg_t *)arg; 802dbed73cbSSangeeta Misra 803dbed73cbSSangeeta Misra /* 804dbed73cbSSangeeta Misra * in full mode, we currently re-open ofmt() for every rule; we use 805dbed73cbSSangeeta Misra * a variable number of lines, as we print one for every server 806dbed73cbSSangeeta Misra * attached to a rule. 807dbed73cbSSangeeta Misra */ 808dbed73cbSSangeeta Misra if (larg->o_str == NULL) { 809dbed73cbSSangeeta Misra ilbadm_err(gettext("internal error")); 810dbed73cbSSangeeta Misra return (ILB_STATUS_GENERIC); 811dbed73cbSSangeeta Misra } 812dbed73cbSSangeeta Misra 813dbed73cbSSangeeta Misra if (larg->flags & ILBADM_LIST_PARSE) 814dbed73cbSSangeeta Misra oflags |= OFMT_PARSABLE; 815dbed73cbSSangeeta Misra 816dbed73cbSSangeeta Misra if (rd->r_vip.ia_af == AF_INET) 817dbed73cbSSangeeta Misra fields = ssfields_v4; 818dbed73cbSSangeeta Misra else 819dbed73cbSSangeeta Misra fields = ssfields_v6; 820dbed73cbSSangeeta Misra 821dbed73cbSSangeeta Misra if (oh == NULL) { 822dbed73cbSSangeeta Misra oerr = ofmt_open(larg->o_str, fields, oflags, ocols, &oh); 823dbed73cbSSangeeta Misra if (oerr != OFMT_SUCCESS) { 824dbed73cbSSangeeta Misra char e[80]; 825dbed73cbSSangeeta Misra 826dbed73cbSSangeeta Misra ilbadm_err(gettext("ofmt_open failed: %s"), 827dbed73cbSSangeeta Misra ofmt_strerror(oh, oerr, e, sizeof (e))); 828dbed73cbSSangeeta Misra return (ILB_STATUS_GENERIC); 829dbed73cbSSangeeta Misra } 830dbed73cbSSangeeta Misra larg->oh = oh; 831dbed73cbSSangeeta Misra } 832dbed73cbSSangeeta Misra 833dbed73cbSSangeeta Misra larg->rd = rd; 834dbed73cbSSangeeta Misra larg->sgname = rd->r_sgname; 835dbed73cbSSangeeta Misra 836dbed73cbSSangeeta Misra return (ilb_walk_servers(h, i_show_rl_srv, rd->r_sgname, (void *)larg)); 837dbed73cbSSangeeta Misra } 838dbed73cbSSangeeta Misra 839dbed73cbSSangeeta Misra static char *def_show_srv_hdrs = 840dbed73cbSSangeeta Misra "SERVERID,ADDRESS,PORT,RULENAME,STATUS,SERVERGROUP"; 841dbed73cbSSangeeta Misra 842dbed73cbSSangeeta Misra /* ARGSUSED */ 843dbed73cbSSangeeta Misra ilbadm_status_t 844dbed73cbSSangeeta Misra ilbadm_show_server(int argc, char *argv[]) 845dbed73cbSSangeeta Misra { 846dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE; 847dbed73cbSSangeeta Misra int c; 848dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK; 849dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK; 850dbed73cbSSangeeta Misra boolean_t o_opt = B_FALSE, p_opt = B_FALSE; 851dbed73cbSSangeeta Misra ilbadm_rl_srvlist_arg_t larg; 852dbed73cbSSangeeta Misra 853dbed73cbSSangeeta Misra bzero(&larg, sizeof (larg)); 854dbed73cbSSangeeta Misra while ((c = getopt(argc, argv, ":po:")) != -1) { 855dbed73cbSSangeeta Misra switch ((char)c) { 856dbed73cbSSangeeta Misra case 'p': larg.flags |= ILBADM_LIST_PARSE; 857dbed73cbSSangeeta Misra p_opt = B_TRUE; 858dbed73cbSSangeeta Misra break; 859dbed73cbSSangeeta Misra case 'o': larg.o_str = optarg; 860dbed73cbSSangeeta Misra o_opt = B_TRUE; 861dbed73cbSSangeeta Misra break; 862dbed73cbSSangeeta Misra case ':': ilbadm_err(gettext("missing option argument for %c"), 863dbed73cbSSangeeta Misra (char)optopt); 864dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 865dbed73cbSSangeeta Misra goto out; 866dbed73cbSSangeeta Misra case '?': 867dbed73cbSSangeeta Misra default: 868dbed73cbSSangeeta Misra unknown_opt(argv, optind-1); 869dbed73cbSSangeeta Misra /* not reached */ 870dbed73cbSSangeeta Misra break; 871dbed73cbSSangeeta Misra } 872dbed73cbSSangeeta Misra } 873dbed73cbSSangeeta Misra 874dbed73cbSSangeeta Misra if (p_opt && !o_opt) { 875dbed73cbSSangeeta Misra ilbadm_err(gettext("option -p requires -o")); 876dbed73cbSSangeeta Misra exit(1); 877dbed73cbSSangeeta Misra } 878dbed73cbSSangeeta Misra 879dbed73cbSSangeeta Misra if (p_opt && larg.o_str != NULL && 880dbed73cbSSangeeta Misra (strcasecmp(larg.o_str, "all") == 0)) { 881dbed73cbSSangeeta Misra ilbadm_err(gettext("option -p requires explicit" 882dbed73cbSSangeeta Misra " field names for -o")); 883dbed73cbSSangeeta Misra exit(1); 884dbed73cbSSangeeta Misra } 885dbed73cbSSangeeta Misra 886dbed73cbSSangeeta Misra /* no -o option, so we use default fields */ 887dbed73cbSSangeeta Misra if (!o_opt) 888dbed73cbSSangeeta Misra larg.o_str = def_show_srv_hdrs; 889dbed73cbSSangeeta Misra 890dbed73cbSSangeeta Misra rclib = ilb_open(&h); 891dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) 892dbed73cbSSangeeta Misra goto out; 893dbed73cbSSangeeta Misra 894dbed73cbSSangeeta Misra if (optind >= argc) { 895dbed73cbSSangeeta Misra rclib = ilb_walk_rules(h, ilbadm_show_rl_servers, NULL, 896dbed73cbSSangeeta Misra (void*)&larg); 897dbed73cbSSangeeta Misra } else { 898dbed73cbSSangeeta Misra while (optind < argc) { 899dbed73cbSSangeeta Misra rclib = ilb_walk_rules(h, ilbadm_show_rl_servers, 900dbed73cbSSangeeta Misra argv[optind++], (void*)&larg); 901dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) 902dbed73cbSSangeeta Misra break; 903dbed73cbSSangeeta Misra } 904dbed73cbSSangeeta Misra } 905dbed73cbSSangeeta Misra out: 906dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE) 907dbed73cbSSangeeta Misra (void) ilb_close(h); 908dbed73cbSSangeeta Misra 909dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) { 910dbed73cbSSangeeta Misra /* 911dbed73cbSSangeeta Misra * The show function returns ILB_STATUS_GENERIC after printing 912dbed73cbSSangeeta Misra * out an error message. So we don't need to print it again. 913dbed73cbSSangeeta Misra */ 914dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_GENERIC) 915dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib)); 916dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 917dbed73cbSSangeeta Misra } 918dbed73cbSSangeeta Misra return (rc); 919dbed73cbSSangeeta Misra } 920dbed73cbSSangeeta Misra 921dbed73cbSSangeeta Misra static ilbadm_status_t 922dbed73cbSSangeeta Misra i_parse_rl_arg(char *arg, ilb_rule_data_t *rd, ilbadm_key_name_t *keylist) 923dbed73cbSSangeeta Misra { 924dbed73cbSSangeeta Misra ilbadm_status_t rc; 925dbed73cbSSangeeta Misra 926dbed73cbSSangeeta Misra rc = i_parse_optstring(arg, (void *) rd, keylist, 927dbed73cbSSangeeta Misra OPT_PORTS, NULL); 928dbed73cbSSangeeta Misra return (rc); 929dbed73cbSSangeeta Misra } 930dbed73cbSSangeeta Misra 931dbed73cbSSangeeta Misra static void 932dbed73cbSSangeeta Misra i_ilbadm_alloc_rule(ilb_rule_data_t **rdp) 933dbed73cbSSangeeta Misra { 934dbed73cbSSangeeta Misra ilb_rule_data_t *rd; 935dbed73cbSSangeeta Misra 936dbed73cbSSangeeta Misra *rdp = rd = (ilb_rule_data_t *)calloc(sizeof (*rd), 1); 937dbed73cbSSangeeta Misra if (rd == NULL) 938dbed73cbSSangeeta Misra return; 939dbed73cbSSangeeta Misra rd->r_proto = IPPROTO_TCP; 940dbed73cbSSangeeta Misra } 941dbed73cbSSangeeta Misra 942dbed73cbSSangeeta Misra static void 943dbed73cbSSangeeta Misra i_ilbadm_free_rule(ilb_rule_data_t *rd) 944dbed73cbSSangeeta Misra { 945dbed73cbSSangeeta Misra free(rd); 946dbed73cbSSangeeta Misra } 947dbed73cbSSangeeta Misra 948dbed73cbSSangeeta Misra /* ARGSUSED */ 949dbed73cbSSangeeta Misra ilbadm_status_t 950dbed73cbSSangeeta Misra ilbadm_destroy_rule(int argc, char *argv[]) 951dbed73cbSSangeeta Misra { 952dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE; 953dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK; 954dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK; 955dbed73cbSSangeeta Misra boolean_t all_rules = B_FALSE; 956dbed73cbSSangeeta Misra int c, i; 957dbed73cbSSangeeta Misra 958dbed73cbSSangeeta Misra while ((c = getopt(argc, argv, ":a")) != -1) { 959dbed73cbSSangeeta Misra switch ((char)c) { 960dbed73cbSSangeeta Misra case 'a': 961dbed73cbSSangeeta Misra all_rules = B_TRUE; 962dbed73cbSSangeeta Misra break; 963dbed73cbSSangeeta Misra case '?': 964dbed73cbSSangeeta Misra default: 965dbed73cbSSangeeta Misra unknown_opt(argv, optind-1); 966dbed73cbSSangeeta Misra /* not reached */ 967dbed73cbSSangeeta Misra break; 968dbed73cbSSangeeta Misra } 969dbed73cbSSangeeta Misra } 970dbed73cbSSangeeta Misra 971dbed73cbSSangeeta Misra if (optind >= argc && !all_rules) { 972dbed73cbSSangeeta Misra ilbadm_err(gettext("usage: delete-rule -a | name")); 973dbed73cbSSangeeta Misra return (ILBADM_LIBERR); 974dbed73cbSSangeeta Misra } 975dbed73cbSSangeeta Misra 976dbed73cbSSangeeta Misra /* either "-a" or rulename, not both */ 977dbed73cbSSangeeta Misra if (optind < argc && all_rules) { 978dbed73cbSSangeeta Misra rc = ILBADM_INVAL_ARGS; 979dbed73cbSSangeeta Misra goto out; 980dbed73cbSSangeeta Misra } 981dbed73cbSSangeeta Misra 982dbed73cbSSangeeta Misra rclib = ilb_open(&h); 983dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) 984dbed73cbSSangeeta Misra goto out; 985dbed73cbSSangeeta Misra 986dbed73cbSSangeeta Misra if (all_rules) { 987dbed73cbSSangeeta Misra rclib = ilb_destroy_rule(h, NULL); 988dbed73cbSSangeeta Misra goto out; 989dbed73cbSSangeeta Misra } 990dbed73cbSSangeeta Misra 991dbed73cbSSangeeta Misra for (i = optind; i < argc && rclib == ILB_STATUS_OK; i++) 992dbed73cbSSangeeta Misra rclib = ilb_destroy_rule(h, argv[i]); 993dbed73cbSSangeeta Misra 994dbed73cbSSangeeta Misra out: 995dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE) 996dbed73cbSSangeeta Misra (void) ilb_close(h); 997dbed73cbSSangeeta Misra 998dbed73cbSSangeeta Misra /* This prints the specific errors */ 999dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) { 1000dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib)); 1001dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1002dbed73cbSSangeeta Misra } 1003dbed73cbSSangeeta Misra /* This prints the generic errors */ 1004dbed73cbSSangeeta Misra if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR)) 1005dbed73cbSSangeeta Misra ilbadm_err(ilbadm_errstr(rc)); 1006dbed73cbSSangeeta Misra return (rc); 1007dbed73cbSSangeeta Misra } 1008dbed73cbSSangeeta Misra 1009dbed73cbSSangeeta Misra /* ARGSUSED */ 1010dbed73cbSSangeeta Misra static ilbadm_status_t 1011dbed73cbSSangeeta Misra ilbadm_Xable_rule(int argc, char *argv[], ilbadm_cmd_t cmd) 1012dbed73cbSSangeeta Misra { 1013dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE; 1014dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK; 1015dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK; 1016dbed73cbSSangeeta Misra int i; 1017dbed73cbSSangeeta Misra 1018dbed73cbSSangeeta Misra rclib = ilb_open(&h); 1019dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) 1020dbed73cbSSangeeta Misra goto out; 1021dbed73cbSSangeeta Misra /* 1022dbed73cbSSangeeta Misra * by default, en/disable-rule mean "all", and not using 1023dbed73cbSSangeeta Misra * a rule name will cause this behaviour to kick in 1024dbed73cbSSangeeta Misra */ 1025dbed73cbSSangeeta Misra if (argc < 2) { 1026dbed73cbSSangeeta Misra if (cmd == cmd_enable_rule) 1027dbed73cbSSangeeta Misra rclib = ilb_enable_rule(h, NULL); 1028dbed73cbSSangeeta Misra else 1029dbed73cbSSangeeta Misra rclib = ilb_disable_rule(h, NULL); 1030dbed73cbSSangeeta Misra } else { 1031dbed73cbSSangeeta Misra 1032dbed73cbSSangeeta Misra for (i = optind; i < argc && rc == ILBADM_OK; i++) { 1033dbed73cbSSangeeta Misra if (cmd == cmd_enable_rule) 1034dbed73cbSSangeeta Misra rclib = ilb_enable_rule(h, argv[i]); 1035dbed73cbSSangeeta Misra else 1036dbed73cbSSangeeta Misra rclib = ilb_disable_rule(h, argv[i]); 1037dbed73cbSSangeeta Misra } 1038dbed73cbSSangeeta Misra } 1039dbed73cbSSangeeta Misra out: 1040dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE) 1041dbed73cbSSangeeta Misra (void) ilb_close(h); 1042dbed73cbSSangeeta Misra 1043dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) { 1044dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib)); 1045dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1046dbed73cbSSangeeta Misra } 1047dbed73cbSSangeeta Misra return (rc); 1048dbed73cbSSangeeta Misra } 1049dbed73cbSSangeeta Misra 1050dbed73cbSSangeeta Misra ilbadm_status_t 1051dbed73cbSSangeeta Misra ilbadm_enable_rule(int argc, char *argv[]) 1052dbed73cbSSangeeta Misra { 1053dbed73cbSSangeeta Misra 1054dbed73cbSSangeeta Misra return (ilbadm_Xable_rule(argc, argv, cmd_enable_rule)); 1055dbed73cbSSangeeta Misra } 1056dbed73cbSSangeeta Misra 1057dbed73cbSSangeeta Misra ilbadm_status_t 1058dbed73cbSSangeeta Misra ilbadm_disable_rule(int argc, char *argv[]) 1059dbed73cbSSangeeta Misra { 1060dbed73cbSSangeeta Misra return (ilbadm_Xable_rule(argc, argv, cmd_disable_rule)); 1061dbed73cbSSangeeta Misra } 1062dbed73cbSSangeeta Misra 1063dbed73cbSSangeeta Misra /* 1064dbed73cbSSangeeta Misra * parse and create a rule 1065dbed73cbSSangeeta Misra */ 1066dbed73cbSSangeeta Misra ilbadm_status_t 1067dbed73cbSSangeeta Misra ilbadm_create_rule(int argc, char *argv[]) 1068dbed73cbSSangeeta Misra { 1069dbed73cbSSangeeta Misra ilb_handle_t h = ILB_INVALID_HANDLE; 1070dbed73cbSSangeeta Misra int c; 1071dbed73cbSSangeeta Misra ilb_status_t rclib = ILB_STATUS_OK; 1072dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK; 1073dbed73cbSSangeeta Misra ilb_rule_data_t *rd; 1074dbed73cbSSangeeta Misra boolean_t p_opt = B_FALSE; 1075dbed73cbSSangeeta Misra 1076dbed73cbSSangeeta Misra i_ilbadm_alloc_rule(&rd); 1077dbed73cbSSangeeta Misra 1078dbed73cbSSangeeta Misra while ((c = getopt(argc, argv, ":ei:m:o:t:h:p")) != -1) { 1079dbed73cbSSangeeta Misra switch ((char)c) { 1080dbed73cbSSangeeta Misra case 'e': 1081dbed73cbSSangeeta Misra rd->r_flags |= ILB_FLAGS_RULE_ENABLED; 1082dbed73cbSSangeeta Misra break; 1083dbed73cbSSangeeta Misra case 'h': 1084dbed73cbSSangeeta Misra /* 1085dbed73cbSSangeeta Misra * Default value of of r_hcpflag means that if there 1086dbed73cbSSangeeta Misra * is a port range, probe any port. If there is only 1087dbed73cbSSangeeta Misra * one port, probe that port. 1088dbed73cbSSangeeta Misra */ 1089dbed73cbSSangeeta Misra rd->r_hcpflag = ILB_HCI_PROBE_ANY; 1090dbed73cbSSangeeta Misra rc = i_parse_rl_arg(optarg, rd, &rl_healthchk_keys[0]); 1091dbed73cbSSangeeta Misra break; 1092dbed73cbSSangeeta Misra case 'o': 1093dbed73cbSSangeeta Misra rc = i_parse_rl_arg(optarg, rd, &rl_outgoing_keys[0]); 1094dbed73cbSSangeeta Misra break; 1095dbed73cbSSangeeta Misra case 'm': 1096dbed73cbSSangeeta Misra rc = i_parse_rl_arg(optarg, rd, &rl_method_keys[0]); 1097dbed73cbSSangeeta Misra break; 1098dbed73cbSSangeeta Misra case 't': 1099dbed73cbSSangeeta Misra rc = i_parse_rl_arg(optarg, rd, &rl_timer_keys[0]); 1100dbed73cbSSangeeta Misra break; 1101dbed73cbSSangeeta Misra case 'i': 1102dbed73cbSSangeeta Misra rc = i_parse_rl_arg(optarg, rd, &rl_incoming_keys[0]); 1103dbed73cbSSangeeta Misra break; 1104dbed73cbSSangeeta Misra case 'p': 1105dbed73cbSSangeeta Misra p_opt = B_TRUE; 1106dbed73cbSSangeeta Misra break; 1107dbed73cbSSangeeta Misra case ':': 1108dbed73cbSSangeeta Misra ilbadm_err(gettext("missing option-argument" 1109dbed73cbSSangeeta Misra " for %c"), (char)optopt); 1110dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1111dbed73cbSSangeeta Misra break; 1112dbed73cbSSangeeta Misra case '?': 1113dbed73cbSSangeeta Misra default: 1114dbed73cbSSangeeta Misra unknown_opt(argv, optind-1); 1115dbed73cbSSangeeta Misra /* not reached */ 1116dbed73cbSSangeeta Misra break; 1117dbed73cbSSangeeta Misra 1118dbed73cbSSangeeta Misra } 1119dbed73cbSSangeeta Misra if (rc != ILBADM_OK) 1120dbed73cbSSangeeta Misra goto out; 1121dbed73cbSSangeeta Misra } 1122dbed73cbSSangeeta Misra 1123dbed73cbSSangeeta Misra if (optind >= argc) { 1124dbed73cbSSangeeta Misra ilbadm_err(gettext("missing mandatory arguments - please refer" 1125dbed73cbSSangeeta Misra " to 'ilbadm create-rule' subcommand description in" 1126dbed73cbSSangeeta Misra " ilbadm(1M)")); 1127dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1128dbed73cbSSangeeta Misra goto out; 1129dbed73cbSSangeeta Misra 1130dbed73cbSSangeeta Misra } 1131dbed73cbSSangeeta Misra 1132dbed73cbSSangeeta Misra if (p_opt) { 1133dbed73cbSSangeeta Misra /* 1134dbed73cbSSangeeta Misra * if user hasn't specified a mask, apply default 1135dbed73cbSSangeeta Misra */ 1136dbed73cbSSangeeta Misra if ((rd->r_flags & ILB_FLAGS_RULE_STICKY) == 0) { 1137dbed73cbSSangeeta Misra char *maskstr; 1138dbed73cbSSangeeta Misra 1139dbed73cbSSangeeta Misra switch (rd->r_vip.ia_af) { 1140dbed73cbSSangeeta Misra case AF_INET: 1141dbed73cbSSangeeta Misra maskstr = "32"; 1142dbed73cbSSangeeta Misra break; 1143dbed73cbSSangeeta Misra case AF_INET6: 1144dbed73cbSSangeeta Misra maskstr = "128"; 1145dbed73cbSSangeeta Misra break; 1146dbed73cbSSangeeta Misra } 1147dbed73cbSSangeeta Misra rc = ilbadm_set_netmask(maskstr, &rd->r_stickymask, 1148dbed73cbSSangeeta Misra rd->r_vip.ia_af); 1149dbed73cbSSangeeta Misra if (rc != ILBADM_OK) { 1150dbed73cbSSangeeta Misra ilbadm_err(gettext("trouble seting default" 1151dbed73cbSSangeeta Misra " persistence mask")); 1152dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1153dbed73cbSSangeeta Misra goto out; 1154dbed73cbSSangeeta Misra } 1155dbed73cbSSangeeta Misra } 1156dbed73cbSSangeeta Misra } else { 1157dbed73cbSSangeeta Misra /* use of sticky mask currently mandates "-p" */ 1158dbed73cbSSangeeta Misra if ((rd->r_flags & ILB_FLAGS_RULE_STICKY) != 0) { 1159dbed73cbSSangeeta Misra ilbadm_err(gettext("use of stickymask requires" 1160dbed73cbSSangeeta Misra " -p option")); 1161dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1162dbed73cbSSangeeta Misra goto out; 1163dbed73cbSSangeeta Misra } 1164dbed73cbSSangeeta Misra } 1165dbed73cbSSangeeta Misra 1166dbed73cbSSangeeta Misra if (strlen(argv[optind]) > ILBD_NAMESZ -1) { 1167dbed73cbSSangeeta Misra ilbadm_err(gettext("rule name %s is too long -" 1168dbed73cbSSangeeta Misra " must not exceed %d chars"), argv[optind], 1169dbed73cbSSangeeta Misra ILBD_NAMESZ - 1); 1170dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1171dbed73cbSSangeeta Misra goto out; 1172dbed73cbSSangeeta Misra } 1173dbed73cbSSangeeta Misra 1174dbed73cbSSangeeta Misra (void) strlcpy(rd->r_name, argv[optind], sizeof (rd->r_name)); 1175dbed73cbSSangeeta Misra 1176dbed73cbSSangeeta Misra rc = i_check_rule_spec(rd); 1177dbed73cbSSangeeta Misra if (rc != ILBADM_OK) 1178dbed73cbSSangeeta Misra goto out; 1179dbed73cbSSangeeta Misra 1180dbed73cbSSangeeta Misra rclib = ilb_open(&h); 1181dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) 1182dbed73cbSSangeeta Misra goto out; 1183dbed73cbSSangeeta Misra 1184dbed73cbSSangeeta Misra rclib = ilb_create_rule(h, rd); 1185dbed73cbSSangeeta Misra 1186dbed73cbSSangeeta Misra out: 1187dbed73cbSSangeeta Misra i_ilbadm_free_rule(rd); 1188dbed73cbSSangeeta Misra 1189dbed73cbSSangeeta Misra if (h != ILB_INVALID_HANDLE) 1190dbed73cbSSangeeta Misra (void) ilb_close(h); 1191dbed73cbSSangeeta Misra 1192dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) { 1193dbed73cbSSangeeta Misra ilbadm_err(ilb_errstr(rclib)); 1194dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1195dbed73cbSSangeeta Misra } 1196dbed73cbSSangeeta Misra if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR)) 1197dbed73cbSSangeeta Misra ilbadm_err(ilbadm_errstr(rc)); 1198dbed73cbSSangeeta Misra 1199dbed73cbSSangeeta Misra return (rc); 1200dbed73cbSSangeeta Misra } 1201dbed73cbSSangeeta Misra 1202dbed73cbSSangeeta Misra /* ARGSUSED */ 1203dbed73cbSSangeeta Misra 1204dbed73cbSSangeeta Misra /* 1205dbed73cbSSangeeta Misra * Since this function is used by libilb function, ilb_walk_rules() 1206dbed73cbSSangeeta Misra * it must return libilb errors 1207dbed73cbSSangeeta Misra */ 1208dbed73cbSSangeeta Misra static ilb_status_t 1209dbed73cbSSangeeta Misra ilbadm_export_rl(ilb_handle_t h, ilb_rule_data_t *rd, void *arg) 1210dbed73cbSSangeeta Misra { 1211dbed73cbSSangeeta Misra char linebuf[128]; /* should be enough */ 1212dbed73cbSSangeeta Misra int sz = sizeof (linebuf); 1213dbed73cbSSangeeta Misra FILE *fp = ((ilbadm_rl_exp_arg_t *)arg)->fp; 1214dbed73cbSSangeeta Misra uint32_t conndrain, nat_timeout, sticky_timeout; 1215dbed73cbSSangeeta Misra 1216dbed73cbSSangeeta Misra (void) fprintf(fp, "create-rule "); 1217dbed73cbSSangeeta Misra if (rd->r_flags & ILB_FLAGS_RULE_ENABLED) 1218dbed73cbSSangeeta Misra (void) fprintf(fp, "-e "); 1219dbed73cbSSangeeta Misra if (rd->r_flags & ILB_FLAGS_RULE_STICKY) 1220dbed73cbSSangeeta Misra (void) fprintf(fp, "-p "); 1221dbed73cbSSangeeta Misra 1222dbed73cbSSangeeta Misra ip2str(&rd->r_vip, linebuf, sz, V6_ADDRONLY); 1223dbed73cbSSangeeta Misra (void) fprintf(fp, "-i vip=%s,", linebuf); 1224dbed73cbSSangeeta Misra 1225dbed73cbSSangeeta Misra (void) ports2str(ntohs(rd->r_minport), ntohs(rd->r_maxport), 1226dbed73cbSSangeeta Misra linebuf, sz); 1227dbed73cbSSangeeta Misra (void) fprintf(fp, "%s,", linebuf); 1228dbed73cbSSangeeta Misra 1229dbed73cbSSangeeta Misra proto2str(rd->r_proto, linebuf, sz); 1230dbed73cbSSangeeta Misra (void) fprintf(fp, "%s ", linebuf); 1231dbed73cbSSangeeta Misra 1232dbed73cbSSangeeta Misra algo2str(rd->r_algo, linebuf, sz); 1233dbed73cbSSangeeta Misra (void) fprintf(fp, "-m %s,", linebuf); 1234dbed73cbSSangeeta Misra 1235dbed73cbSSangeeta Misra topo2str(rd->r_topo, linebuf, sz); 1236dbed73cbSSangeeta Misra (void) fprintf(fp, "%s", linebuf); 1237dbed73cbSSangeeta Misra 1238dbed73cbSSangeeta Misra if (rd->r_nat_src_start.ia_af != AF_UNSPEC) { 1239dbed73cbSSangeeta Misra ip2str(&rd->r_nat_src_start, linebuf, sz, V6_ADDRONLY); 1240dbed73cbSSangeeta Misra /* if the address is unspecified, skip it */ 1241dbed73cbSSangeeta Misra if (linebuf[0] != '\0') { 1242dbed73cbSSangeeta Misra (void) fprintf(fp, ",proxy-src=%s", linebuf); 1243dbed73cbSSangeeta Misra ip2str(&rd->r_nat_src_end, linebuf, sz, V6_ADDRONLY); 1244dbed73cbSSangeeta Misra (void) fprintf(fp, "-%s", linebuf); 1245dbed73cbSSangeeta Misra } 1246dbed73cbSSangeeta Misra } 1247dbed73cbSSangeeta Misra 1248dbed73cbSSangeeta Misra if (rd->r_flags & ILB_FLAGS_RULE_STICKY) { 1249dbed73cbSSangeeta Misra (void) fprintf(fp, ",pmask=/%d", 1250dbed73cbSSangeeta Misra ilbadm_mask_to_prefixlen(&rd->r_stickymask)); 1251dbed73cbSSangeeta Misra } 1252dbed73cbSSangeeta Misra 1253dbed73cbSSangeeta Misra (void) fprintf(fp, " "); 1254dbed73cbSSangeeta Misra 1255dbed73cbSSangeeta Misra if (*rd->r_hcname != '\0') { 1256dbed73cbSSangeeta Misra (void) fprintf(fp, "-h hc-name=%s", rd->r_hcname); 1257dbed73cbSSangeeta Misra hcport_print(rd, linebuf, sizeof (linebuf)); 1258dbed73cbSSangeeta Misra 1259dbed73cbSSangeeta Misra if (linebuf[0] != '\0') 1260dbed73cbSSangeeta Misra (void) fprintf(fp, ",hc-port=%s", linebuf); 1261dbed73cbSSangeeta Misra (void) fprintf(fp, " "); 1262dbed73cbSSangeeta Misra } 1263dbed73cbSSangeeta Misra 1264dbed73cbSSangeeta Misra conndrain = rd->r_conndrain; 1265dbed73cbSSangeeta Misra nat_timeout = rd->r_nat_timeout; 1266dbed73cbSSangeeta Misra sticky_timeout = rd->r_sticky_timeout; 1267dbed73cbSSangeeta Misra if (conndrain != 0 || nat_timeout != 0 || sticky_timeout != 0) { 1268dbed73cbSSangeeta Misra int cnt = 0; 1269dbed73cbSSangeeta Misra 1270dbed73cbSSangeeta Misra (void) fprintf(fp, "-t "); 1271dbed73cbSSangeeta Misra if (conndrain != 0) { 1272dbed73cbSSangeeta Misra cnt++; 1273dbed73cbSSangeeta Misra (void) fprintf(fp, "conn-drain=%u", conndrain); 1274dbed73cbSSangeeta Misra } 1275dbed73cbSSangeeta Misra if (nat_timeout != 0) { 1276dbed73cbSSangeeta Misra if (cnt > 0) 1277dbed73cbSSangeeta Misra (void) fprintf(fp, ","); 1278dbed73cbSSangeeta Misra cnt++; 1279dbed73cbSSangeeta Misra (void) fprintf(fp, "nat-timeout=%u", nat_timeout); 1280dbed73cbSSangeeta Misra } 1281dbed73cbSSangeeta Misra if (sticky_timeout != 0) { 1282dbed73cbSSangeeta Misra if (cnt > 0) 1283dbed73cbSSangeeta Misra (void) fprintf(fp, ","); 1284dbed73cbSSangeeta Misra (void) fprintf(fp, "persist-timeout=%u", 1285dbed73cbSSangeeta Misra sticky_timeout); 1286dbed73cbSSangeeta Misra } 1287dbed73cbSSangeeta Misra (void) fprintf(fp, " "); 1288dbed73cbSSangeeta Misra } 1289dbed73cbSSangeeta Misra 1290dbed73cbSSangeeta Misra if (fprintf(fp, "-o servergroup=%s %s\n", rd->r_sgname, rd->r_name) 1291dbed73cbSSangeeta Misra < 0 || fflush(fp) == EOF) 1292dbed73cbSSangeeta Misra return (ILB_STATUS_WRITE); 1293dbed73cbSSangeeta Misra 1294dbed73cbSSangeeta Misra return (ILB_STATUS_OK); 1295dbed73cbSSangeeta Misra } 1296dbed73cbSSangeeta Misra 1297dbed73cbSSangeeta Misra ilbadm_status_t 1298dbed73cbSSangeeta Misra ilbadm_export_rules(ilb_handle_t h, FILE *fp) 1299dbed73cbSSangeeta Misra { 1300dbed73cbSSangeeta Misra ilb_status_t rclib; 1301dbed73cbSSangeeta Misra ilbadm_status_t rc = ILBADM_OK; 1302dbed73cbSSangeeta Misra ilbadm_rl_exp_arg_t arg; 1303dbed73cbSSangeeta Misra 1304dbed73cbSSangeeta Misra arg.fp = fp; 1305dbed73cbSSangeeta Misra 1306dbed73cbSSangeeta Misra rclib = ilb_walk_rules(h, ilbadm_export_rl, NULL, (void *)&arg); 1307dbed73cbSSangeeta Misra if (rclib != ILB_STATUS_OK) 1308dbed73cbSSangeeta Misra rc = ILBADM_LIBERR; 1309dbed73cbSSangeeta Misra return (rc); 1310dbed73cbSSangeeta Misra } 1311