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