xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/ilbadm/ilbadm_sg.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 <stddef.h>
32*10946SSangeeta.Misra@Sun.COM #include <assert.h>
33*10946SSangeeta.Misra@Sun.COM #include <errno.h>
34*10946SSangeeta.Misra@Sun.COM #include <sys/types.h>
35*10946SSangeeta.Misra@Sun.COM #include <sys/socket.h>
36*10946SSangeeta.Misra@Sun.COM #include <netinet/in.h>
37*10946SSangeeta.Misra@Sun.COM #include <arpa/inet.h>
38*10946SSangeeta.Misra@Sun.COM #include <sys/list.h>
39*10946SSangeeta.Misra@Sun.COM #include <ofmt.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 servrange_keys[] = {
44*10946SSangeeta.Misra@Sun.COM 	{ILB_KEY_SERVER, "server", "servers"},
45*10946SSangeeta.Misra@Sun.COM 	{ILB_KEY_SERVRANGE, "server", "servers"},
46*10946SSangeeta.Misra@Sun.COM 	{ILB_KEY_BAD, "", ""}
47*10946SSangeeta.Misra@Sun.COM };
48*10946SSangeeta.Misra@Sun.COM 
49*10946SSangeeta.Misra@Sun.COM static ilbadm_key_name_t serverID_keys[] = {
50*10946SSangeeta.Misra@Sun.COM 	{ILB_KEY_SERVERID, "server", ""},
51*10946SSangeeta.Misra@Sun.COM 	{ILB_KEY_BAD, "", ""}
52*10946SSangeeta.Misra@Sun.COM };
53*10946SSangeeta.Misra@Sun.COM 
54*10946SSangeeta.Misra@Sun.COM typedef struct sg_export_arg {
55*10946SSangeeta.Misra@Sun.COM 	FILE		*fp;
56*10946SSangeeta.Misra@Sun.COM 	ilbadm_sgroup_t	*sg;
57*10946SSangeeta.Misra@Sun.COM } sg_export_arg_t;
58*10946SSangeeta.Misra@Sun.COM 
59*10946SSangeeta.Misra@Sun.COM typedef struct arg_struct {
60*10946SSangeeta.Misra@Sun.COM 	int		flags;
61*10946SSangeeta.Misra@Sun.COM 	char		*o_str;
62*10946SSangeeta.Misra@Sun.COM 	ofmt_field_t	*o_fields;
63*10946SSangeeta.Misra@Sun.COM 	ofmt_handle_t	oh;
64*10946SSangeeta.Misra@Sun.COM } list_arg_t;
65*10946SSangeeta.Misra@Sun.COM 
66*10946SSangeeta.Misra@Sun.COM typedef struct sg_srv_o_struct {
67*10946SSangeeta.Misra@Sun.COM 	char		*sgname;
68*10946SSangeeta.Misra@Sun.COM 	ilb_server_data_t	*sd;
69*10946SSangeeta.Misra@Sun.COM } sg_srv_o_arg_t;
70*10946SSangeeta.Misra@Sun.COM 
71*10946SSangeeta.Misra@Sun.COM static ofmt_cb_t of_sgname;
72*10946SSangeeta.Misra@Sun.COM static ofmt_cb_t of_srvID;
73*10946SSangeeta.Misra@Sun.COM static ofmt_cb_t of_port;
74*10946SSangeeta.Misra@Sun.COM static ofmt_cb_t of_ip;
75*10946SSangeeta.Misra@Sun.COM 
76*10946SSangeeta.Misra@Sun.COM static ofmt_field_t sgfields_v4[] = {
77*10946SSangeeta.Misra@Sun.COM 	{"SGNAME", ILB_SGNAME_SZ, 0, of_sgname},
78*10946SSangeeta.Misra@Sun.COM 	{"SERVERID", ILB_NAMESZ, 0, of_srvID},
79*10946SSangeeta.Misra@Sun.COM 	{"MINPORT", 8, 0, of_port},
80*10946SSangeeta.Misra@Sun.COM 	{"MAXPORT", 8, 1, of_port},
81*10946SSangeeta.Misra@Sun.COM 	{"IP_ADDRESS", 15, 0, of_ip},
82*10946SSangeeta.Misra@Sun.COM 	{NULL, 0, 0, NULL}
83*10946SSangeeta.Misra@Sun.COM };
84*10946SSangeeta.Misra@Sun.COM static ofmt_field_t sgfields_v6[] = {
85*10946SSangeeta.Misra@Sun.COM 	{"SGNAME", ILB_SGNAME_SZ, 0, of_sgname},
86*10946SSangeeta.Misra@Sun.COM 	{"SERVERID", ILB_NAMESZ, 0, of_srvID},
87*10946SSangeeta.Misra@Sun.COM 	{"MINPORT", 8, 0, of_port},
88*10946SSangeeta.Misra@Sun.COM 	{"MAXPORT", 8, 1, of_port},
89*10946SSangeeta.Misra@Sun.COM 	{"IP_ADDRESS", 39, 0, of_ip},
90*10946SSangeeta.Misra@Sun.COM 	{NULL, 0, 0, NULL}
91*10946SSangeeta.Misra@Sun.COM };
92*10946SSangeeta.Misra@Sun.COM 
93*10946SSangeeta.Misra@Sun.COM #define	MAXCOLS	80 /* make flexible? */
94*10946SSangeeta.Misra@Sun.COM 
95*10946SSangeeta.Misra@Sun.COM extern int	optind, optopt, opterr;
96*10946SSangeeta.Misra@Sun.COM extern char	*optarg;
97*10946SSangeeta.Misra@Sun.COM 
98*10946SSangeeta.Misra@Sun.COM static boolean_t
of_sgname(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)99*10946SSangeeta.Misra@Sun.COM of_sgname(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
100*10946SSangeeta.Misra@Sun.COM {
101*10946SSangeeta.Misra@Sun.COM 	sg_srv_o_arg_t	*l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
102*10946SSangeeta.Misra@Sun.COM 
103*10946SSangeeta.Misra@Sun.COM 	(void) strlcpy(buf, l->sgname, bufsize);
104*10946SSangeeta.Misra@Sun.COM 	return (B_TRUE);
105*10946SSangeeta.Misra@Sun.COM }
106*10946SSangeeta.Misra@Sun.COM 
107*10946SSangeeta.Misra@Sun.COM static boolean_t
of_srvID(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)108*10946SSangeeta.Misra@Sun.COM of_srvID(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
109*10946SSangeeta.Misra@Sun.COM {
110*10946SSangeeta.Misra@Sun.COM 	sg_srv_o_arg_t	*l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
111*10946SSangeeta.Misra@Sun.COM 
112*10946SSangeeta.Misra@Sun.COM 	(void) strlcpy(buf, l->sd->sd_srvID, bufsize);
113*10946SSangeeta.Misra@Sun.COM 	return (B_TRUE);
114*10946SSangeeta.Misra@Sun.COM }
115*10946SSangeeta.Misra@Sun.COM 
116*10946SSangeeta.Misra@Sun.COM static boolean_t
of_port(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)117*10946SSangeeta.Misra@Sun.COM of_port(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
118*10946SSangeeta.Misra@Sun.COM {
119*10946SSangeeta.Misra@Sun.COM 	sg_srv_o_arg_t	*l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
120*10946SSangeeta.Misra@Sun.COM 	int		port;
121*10946SSangeeta.Misra@Sun.COM 
122*10946SSangeeta.Misra@Sun.COM 	if (of_arg->ofmt_id == 0) {
123*10946SSangeeta.Misra@Sun.COM 		port = ntohs(l->sd->sd_minport);
124*10946SSangeeta.Misra@Sun.COM 		if (port == 0)
125*10946SSangeeta.Misra@Sun.COM 			*buf = '\0';
126*10946SSangeeta.Misra@Sun.COM 		else
127*10946SSangeeta.Misra@Sun.COM 			(void) snprintf(buf, bufsize, "%d", port);
128*10946SSangeeta.Misra@Sun.COM 	} else {
129*10946SSangeeta.Misra@Sun.COM 		port = ntohs(l->sd->sd_maxport);
130*10946SSangeeta.Misra@Sun.COM 		if (port == 0)
131*10946SSangeeta.Misra@Sun.COM 			*buf = '\0';
132*10946SSangeeta.Misra@Sun.COM 		else
133*10946SSangeeta.Misra@Sun.COM 			(void) snprintf(buf, bufsize, "%d", port);
134*10946SSangeeta.Misra@Sun.COM 	}
135*10946SSangeeta.Misra@Sun.COM 	return (B_TRUE);
136*10946SSangeeta.Misra@Sun.COM }
137*10946SSangeeta.Misra@Sun.COM 
138*10946SSangeeta.Misra@Sun.COM static boolean_t
of_ip(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)139*10946SSangeeta.Misra@Sun.COM of_ip(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
140*10946SSangeeta.Misra@Sun.COM {
141*10946SSangeeta.Misra@Sun.COM 	sg_srv_o_arg_t	*l = (sg_srv_o_arg_t *)of_arg->ofmt_cbarg;
142*10946SSangeeta.Misra@Sun.COM 
143*10946SSangeeta.Misra@Sun.COM 	ip2str(&l->sd->sd_addr, buf, bufsize, V6_ADDRONLY);
144*10946SSangeeta.Misra@Sun.COM 	return (B_TRUE);
145*10946SSangeeta.Misra@Sun.COM }
146*10946SSangeeta.Misra@Sun.COM 
147*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
i_list_sg_srv_ofmt(char * sgname,ilb_server_data_t * sd,void * arg)148*10946SSangeeta.Misra@Sun.COM i_list_sg_srv_ofmt(char *sgname, ilb_server_data_t *sd, void *arg)
149*10946SSangeeta.Misra@Sun.COM {
150*10946SSangeeta.Misra@Sun.COM 	list_arg_t	*larg = (list_arg_t *)arg;
151*10946SSangeeta.Misra@Sun.COM 	sg_srv_o_arg_t	line_arg;
152*10946SSangeeta.Misra@Sun.COM 
153*10946SSangeeta.Misra@Sun.COM 	line_arg.sgname = sgname;
154*10946SSangeeta.Misra@Sun.COM 	line_arg.sd = sd;
155*10946SSangeeta.Misra@Sun.COM 	ofmt_print(larg->oh, &line_arg);
156*10946SSangeeta.Misra@Sun.COM 	return (ILBADM_OK);
157*10946SSangeeta.Misra@Sun.COM }
158*10946SSangeeta.Misra@Sun.COM 
159*10946SSangeeta.Misra@Sun.COM /*
160*10946SSangeeta.Misra@Sun.COM  * This function is always called via ilb_walk_servergroups()
161*10946SSangeeta.Misra@Sun.COM  * and so must return libilb errors.
162*10946SSangeeta.Misra@Sun.COM  * That's why we need to retain currently unused "h" argument
163*10946SSangeeta.Misra@Sun.COM  */
164*10946SSangeeta.Misra@Sun.COM /* ARGSUSED */
165*10946SSangeeta.Misra@Sun.COM static ilb_status_t
ilbadm_list_sg_srv(ilb_handle_t h,ilb_server_data_t * sd,const char * sgname,void * arg)166*10946SSangeeta.Misra@Sun.COM ilbadm_list_sg_srv(ilb_handle_t h, ilb_server_data_t *sd, const char *sgname,
167*10946SSangeeta.Misra@Sun.COM     void *arg)
168*10946SSangeeta.Misra@Sun.COM {
169*10946SSangeeta.Misra@Sun.COM 	char		ip_str[2*INET6_ADDRSTRLEN + 3] = "";
170*10946SSangeeta.Misra@Sun.COM 	char		port_str[INET6_ADDRSTRLEN];
171*10946SSangeeta.Misra@Sun.COM 	list_arg_t	*larg = (list_arg_t *)arg;
172*10946SSangeeta.Misra@Sun.COM 	ofmt_status_t	oerr;
173*10946SSangeeta.Misra@Sun.COM 	int		oflags = 0;
174*10946SSangeeta.Misra@Sun.COM 	int		ocols = MAXCOLS;
175*10946SSangeeta.Misra@Sun.COM 	int		h_minport, h_maxport;
176*10946SSangeeta.Misra@Sun.COM 	static ofmt_handle_t	oh = (ofmt_handle_t)NULL;
177*10946SSangeeta.Misra@Sun.COM 	ofmt_field_t	*ofp;
178*10946SSangeeta.Misra@Sun.COM 
179*10946SSangeeta.Misra@Sun.COM 	if (larg->o_str != NULL) {
180*10946SSangeeta.Misra@Sun.COM 		if (oh == NULL) {
181*10946SSangeeta.Misra@Sun.COM 			if (sd->sd_addr.ia_af == AF_INET)
182*10946SSangeeta.Misra@Sun.COM 				ofp = sgfields_v6;
183*10946SSangeeta.Misra@Sun.COM 			else
184*10946SSangeeta.Misra@Sun.COM 				ofp = sgfields_v4;
185*10946SSangeeta.Misra@Sun.COM 
186*10946SSangeeta.Misra@Sun.COM 			if (larg->flags & ILBADM_LIST_PARSE)
187*10946SSangeeta.Misra@Sun.COM 				oflags |= OFMT_PARSABLE;
188*10946SSangeeta.Misra@Sun.COM 
189*10946SSangeeta.Misra@Sun.COM 			oerr = ofmt_open(larg->o_str, ofp, oflags, ocols, &oh);
190*10946SSangeeta.Misra@Sun.COM 			if (oerr != OFMT_SUCCESS) {
191*10946SSangeeta.Misra@Sun.COM 				char	e[80];
192*10946SSangeeta.Misra@Sun.COM 
193*10946SSangeeta.Misra@Sun.COM 				ilbadm_err(gettext("ofmt_open failed: %s"),
194*10946SSangeeta.Misra@Sun.COM 				    ofmt_strerror(oh, oerr, e, sizeof (e)));
195*10946SSangeeta.Misra@Sun.COM 				return (ILB_STATUS_GENERIC);
196*10946SSangeeta.Misra@Sun.COM 			}
197*10946SSangeeta.Misra@Sun.COM 			larg->oh = oh;
198*10946SSangeeta.Misra@Sun.COM 		}
199*10946SSangeeta.Misra@Sun.COM 
200*10946SSangeeta.Misra@Sun.COM 
201*10946SSangeeta.Misra@Sun.COM 		(void) i_list_sg_srv_ofmt((char *)sgname, sd, arg);
202*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_OK);
203*10946SSangeeta.Misra@Sun.COM 	}
204*10946SSangeeta.Misra@Sun.COM 
205*10946SSangeeta.Misra@Sun.COM 	ip2str(&sd->sd_addr, ip_str, sizeof (ip_str), 0);
206*10946SSangeeta.Misra@Sun.COM 
207*10946SSangeeta.Misra@Sun.COM 	h_minport = ntohs(sd->sd_minport);
208*10946SSangeeta.Misra@Sun.COM 	h_maxport = ntohs(sd->sd_maxport);
209*10946SSangeeta.Misra@Sun.COM 	if (h_minport == 0)
210*10946SSangeeta.Misra@Sun.COM 		*port_str = '\0';
211*10946SSangeeta.Misra@Sun.COM 	else if (h_maxport > h_minport)
212*10946SSangeeta.Misra@Sun.COM 		(void) sprintf(port_str, ":%d-%d", h_minport, h_maxport);
213*10946SSangeeta.Misra@Sun.COM 	else
214*10946SSangeeta.Misra@Sun.COM 		(void) sprintf(port_str, ":%d", h_minport);
215*10946SSangeeta.Misra@Sun.COM 
216*10946SSangeeta.Misra@Sun.COM 	(void) printf("%s: id:%s %s%s\n", sgname,
217*10946SSangeeta.Misra@Sun.COM 	    sd->sd_srvID?sd->sd_srvID:"(null)", ip_str, port_str);
218*10946SSangeeta.Misra@Sun.COM 	return (ILB_STATUS_OK);
219*10946SSangeeta.Misra@Sun.COM }
220*10946SSangeeta.Misra@Sun.COM 
221*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilbadm_list_sg(ilb_handle_t h,ilb_sg_data_t * sg,void * arg)222*10946SSangeeta.Misra@Sun.COM ilbadm_list_sg(ilb_handle_t h, ilb_sg_data_t *sg, void *arg)
223*10946SSangeeta.Misra@Sun.COM {
224*10946SSangeeta.Misra@Sun.COM 	if (sg->sgd_srvcount == 0) {
225*10946SSangeeta.Misra@Sun.COM 		ilb_server_data_t	tmp_srv;
226*10946SSangeeta.Misra@Sun.COM 
227*10946SSangeeta.Misra@Sun.COM 		bzero(&tmp_srv, sizeof (tmp_srv));
228*10946SSangeeta.Misra@Sun.COM 		return (ilbadm_list_sg_srv(h, &tmp_srv, sg->sgd_name, arg));
229*10946SSangeeta.Misra@Sun.COM 	}
230*10946SSangeeta.Misra@Sun.COM 
231*10946SSangeeta.Misra@Sun.COM 	return (ilb_walk_servers(h, ilbadm_list_sg_srv, sg->sgd_name, arg));
232*10946SSangeeta.Misra@Sun.COM }
233*10946SSangeeta.Misra@Sun.COM 
234*10946SSangeeta.Misra@Sun.COM static char *def_fields = "SGNAME,SERVERID,MINPORT,MAXPORT,IP_ADDRESS";
235*10946SSangeeta.Misra@Sun.COM 
236*10946SSangeeta.Misra@Sun.COM /* ARGSUSED */
237*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_show_servergroups(int argc,char * argv[])238*10946SSangeeta.Misra@Sun.COM ilbadm_show_servergroups(int argc, char *argv[])
239*10946SSangeeta.Misra@Sun.COM {
240*10946SSangeeta.Misra@Sun.COM 	ilb_handle_t	h = ILB_INVALID_HANDLE;
241*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rclib = ILB_STATUS_OK;
242*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t	rc = ILBADM_OK;
243*10946SSangeeta.Misra@Sun.COM 	int		c;
244*10946SSangeeta.Misra@Sun.COM 	char		optstr[] = ":po:";
245*10946SSangeeta.Misra@Sun.COM 
246*10946SSangeeta.Misra@Sun.COM 	boolean_t	o_opt = B_FALSE, p_opt = B_FALSE;
247*10946SSangeeta.Misra@Sun.COM 	list_arg_t	larg = {0, def_fields, NULL, NULL};
248*10946SSangeeta.Misra@Sun.COM 
249*10946SSangeeta.Misra@Sun.COM 	while ((c = getopt(argc, argv, optstr)) != -1) {
250*10946SSangeeta.Misra@Sun.COM 		switch ((char)c) {
251*10946SSangeeta.Misra@Sun.COM 		case 'p': p_opt = B_TRUE;
252*10946SSangeeta.Misra@Sun.COM 			larg.flags |= ILBADM_LIST_PARSE;
253*10946SSangeeta.Misra@Sun.COM 			break;
254*10946SSangeeta.Misra@Sun.COM 		case 'o': larg.o_str = optarg;
255*10946SSangeeta.Misra@Sun.COM 			o_opt = B_TRUE;
256*10946SSangeeta.Misra@Sun.COM 			break;
257*10946SSangeeta.Misra@Sun.COM 		case ':': ilbadm_err(gettext("missing option argument"
258*10946SSangeeta.Misra@Sun.COM 			    " for %c"), (char)optopt);
259*10946SSangeeta.Misra@Sun.COM 			rc = ILBADM_LIBERR;
260*10946SSangeeta.Misra@Sun.COM 			goto out;
261*10946SSangeeta.Misra@Sun.COM 			/* not reached */
262*10946SSangeeta.Misra@Sun.COM 			break;
263*10946SSangeeta.Misra@Sun.COM 		default: unknown_opt(argv, optind-1);
264*10946SSangeeta.Misra@Sun.COM 			/* not reached */
265*10946SSangeeta.Misra@Sun.COM 			break;
266*10946SSangeeta.Misra@Sun.COM 		}
267*10946SSangeeta.Misra@Sun.COM 	}
268*10946SSangeeta.Misra@Sun.COM 
269*10946SSangeeta.Misra@Sun.COM 	if (p_opt && !o_opt) {
270*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(gettext("option -p requires -o"));
271*10946SSangeeta.Misra@Sun.COM 		exit(1);
272*10946SSangeeta.Misra@Sun.COM 	}
273*10946SSangeeta.Misra@Sun.COM 
274*10946SSangeeta.Misra@Sun.COM 	if (p_opt && larg.o_str != NULL &&
275*10946SSangeeta.Misra@Sun.COM 	    (strcasecmp(larg.o_str, "all") == 0)) {
276*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(gettext("option -p requires explicit field"
277*10946SSangeeta.Misra@Sun.COM 		    " names for -o"));
278*10946SSangeeta.Misra@Sun.COM 		exit(1);
279*10946SSangeeta.Misra@Sun.COM 	}
280*10946SSangeeta.Misra@Sun.COM 
281*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_open(&h);
282*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK)
283*10946SSangeeta.Misra@Sun.COM 		goto out;
284*10946SSangeeta.Misra@Sun.COM 
285*10946SSangeeta.Misra@Sun.COM 	if (optind >= argc) {
286*10946SSangeeta.Misra@Sun.COM 		rclib = ilb_walk_servergroups(h, ilbadm_list_sg, NULL,
287*10946SSangeeta.Misra@Sun.COM 		    (void*)&larg);
288*10946SSangeeta.Misra@Sun.COM 		if (rclib != ILB_STATUS_OK)
289*10946SSangeeta.Misra@Sun.COM 			rc = ILBADM_LIBERR;
290*10946SSangeeta.Misra@Sun.COM 	} else {
291*10946SSangeeta.Misra@Sun.COM 		while (optind < argc) {
292*10946SSangeeta.Misra@Sun.COM 			rclib = ilb_walk_servergroups(h, ilbadm_list_sg,
293*10946SSangeeta.Misra@Sun.COM 			    argv[optind++], (void*)&larg);
294*10946SSangeeta.Misra@Sun.COM 			if (rclib != ILB_STATUS_OK) {
295*10946SSangeeta.Misra@Sun.COM 				rc = ILBADM_LIBERR;
296*10946SSangeeta.Misra@Sun.COM 				break;
297*10946SSangeeta.Misra@Sun.COM 			}
298*10946SSangeeta.Misra@Sun.COM 		}
299*10946SSangeeta.Misra@Sun.COM 	}
300*10946SSangeeta.Misra@Sun.COM 
301*10946SSangeeta.Misra@Sun.COM 	if (larg.oh != NULL)
302*10946SSangeeta.Misra@Sun.COM 		ofmt_close(larg.oh);
303*10946SSangeeta.Misra@Sun.COM out:
304*10946SSangeeta.Misra@Sun.COM 	if (h != ILB_INVALID_HANDLE)
305*10946SSangeeta.Misra@Sun.COM 		(void) ilb_close(h);
306*10946SSangeeta.Misra@Sun.COM 
307*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK) {
308*10946SSangeeta.Misra@Sun.COM 		/*
309*10946SSangeeta.Misra@Sun.COM 		 * The show function returns ILB_STATUS_GENERIC after printing
310*10946SSangeeta.Misra@Sun.COM 		 * out an error message.  So we don't need to print it again.
311*10946SSangeeta.Misra@Sun.COM 		 */
312*10946SSangeeta.Misra@Sun.COM 		if (rclib != ILB_STATUS_GENERIC)
313*10946SSangeeta.Misra@Sun.COM 			ilbadm_err(ilb_errstr(rclib));
314*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
315*10946SSangeeta.Misra@Sun.COM 	}
316*10946SSangeeta.Misra@Sun.COM 
317*10946SSangeeta.Misra@Sun.COM 	return (rc);
318*10946SSangeeta.Misra@Sun.COM }
319*10946SSangeeta.Misra@Sun.COM 
320*10946SSangeeta.Misra@Sun.COM ilbadm_servnode_t *
i_new_sg_elem(ilbadm_sgroup_t * sgp)321*10946SSangeeta.Misra@Sun.COM i_new_sg_elem(ilbadm_sgroup_t *sgp)
322*10946SSangeeta.Misra@Sun.COM {
323*10946SSangeeta.Misra@Sun.COM 	ilbadm_servnode_t *s;
324*10946SSangeeta.Misra@Sun.COM 
325*10946SSangeeta.Misra@Sun.COM 	s = (ilbadm_servnode_t *)calloc(sizeof (*s), 1);
326*10946SSangeeta.Misra@Sun.COM 	if (s != NULL) {
327*10946SSangeeta.Misra@Sun.COM 		list_insert_tail(&sgp->sg_serv_list, s);
328*10946SSangeeta.Misra@Sun.COM 		sgp->sg_count++;
329*10946SSangeeta.Misra@Sun.COM 	}
330*10946SSangeeta.Misra@Sun.COM 	return (s);
331*10946SSangeeta.Misra@Sun.COM }
332*10946SSangeeta.Misra@Sun.COM 
333*10946SSangeeta.Misra@Sun.COM static ilbadm_status_t
i_parse_servrange_list(char * arg,ilbadm_sgroup_t * sgp)334*10946SSangeeta.Misra@Sun.COM i_parse_servrange_list(char *arg, ilbadm_sgroup_t *sgp)
335*10946SSangeeta.Misra@Sun.COM {
336*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t	rc;
337*10946SSangeeta.Misra@Sun.COM 	int		count;
338*10946SSangeeta.Misra@Sun.COM 
339*10946SSangeeta.Misra@Sun.COM 	rc = i_parse_optstring(arg, (void *) sgp, servrange_keys,
340*10946SSangeeta.Misra@Sun.COM 	    OPT_VALUE_LIST|OPT_IP_RANGE|OPT_PORTS, &count);
341*10946SSangeeta.Misra@Sun.COM 	return (rc);
342*10946SSangeeta.Misra@Sun.COM }
343*10946SSangeeta.Misra@Sun.COM 
344*10946SSangeeta.Misra@Sun.COM static ilbadm_status_t
i_parse_serverIDs(char * arg,ilbadm_sgroup_t * sgp)345*10946SSangeeta.Misra@Sun.COM i_parse_serverIDs(char *arg, ilbadm_sgroup_t *sgp)
346*10946SSangeeta.Misra@Sun.COM {
347*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t	rc;
348*10946SSangeeta.Misra@Sun.COM 	int		count;
349*10946SSangeeta.Misra@Sun.COM 
350*10946SSangeeta.Misra@Sun.COM 	rc = i_parse_optstring(arg, (void *) sgp, serverID_keys,
351*10946SSangeeta.Misra@Sun.COM 	    OPT_VALUE_LIST|OPT_PORTS, &count);
352*10946SSangeeta.Misra@Sun.COM 	return (rc);
353*10946SSangeeta.Misra@Sun.COM }
354*10946SSangeeta.Misra@Sun.COM 
355*10946SSangeeta.Misra@Sun.COM static ilbadm_status_t
i_mod_sg(ilb_handle_t h,ilbadm_sgroup_t * sgp,ilbadm_cmd_t cmd,int flags)356*10946SSangeeta.Misra@Sun.COM i_mod_sg(ilb_handle_t h, ilbadm_sgroup_t *sgp, ilbadm_cmd_t cmd,
357*10946SSangeeta.Misra@Sun.COM     int flags)
358*10946SSangeeta.Misra@Sun.COM {
359*10946SSangeeta.Misra@Sun.COM 	ilbadm_servnode_t	*sn;
360*10946SSangeeta.Misra@Sun.COM 	ilb_server_data_t	*srv;
361*10946SSangeeta.Misra@Sun.COM 	ilb_status_t		rclib = ILB_STATUS_OK;
362*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t		rc = ILBADM_OK;
363*10946SSangeeta.Misra@Sun.COM 
364*10946SSangeeta.Misra@Sun.COM 	if (h == ILB_INVALID_HANDLE && cmd != cmd_enable_server &&
365*10946SSangeeta.Misra@Sun.COM 	    cmd != cmd_disable_server)
366*10946SSangeeta.Misra@Sun.COM 		return (ILBADM_LIBERR);
367*10946SSangeeta.Misra@Sun.COM 
368*10946SSangeeta.Misra@Sun.COM 	sn = list_head(&sgp->sg_serv_list);
369*10946SSangeeta.Misra@Sun.COM 	while (sn != NULL) {
370*10946SSangeeta.Misra@Sun.COM 		srv = &sn->s_spec;
371*10946SSangeeta.Misra@Sun.COM 
372*10946SSangeeta.Misra@Sun.COM 		srv->sd_flags |= flags;
373*10946SSangeeta.Misra@Sun.COM 		if (cmd == cmd_create_sg || cmd == cmd_add_srv) {
374*10946SSangeeta.Misra@Sun.COM 			rclib = ilb_add_server_to_group(h, sgp->sg_name,
375*10946SSangeeta.Misra@Sun.COM 			    srv);
376*10946SSangeeta.Misra@Sun.COM 			if (rclib != ILB_STATUS_OK) {
377*10946SSangeeta.Misra@Sun.COM 				char	buf[INET6_ADDRSTRLEN + 1];
378*10946SSangeeta.Misra@Sun.COM 
379*10946SSangeeta.Misra@Sun.COM 				rc = ILBADM_LIBERR;
380*10946SSangeeta.Misra@Sun.COM 				ip2str(&srv->sd_addr, buf, sizeof (buf),
381*10946SSangeeta.Misra@Sun.COM 				    V6_ADDRONLY);
382*10946SSangeeta.Misra@Sun.COM 				ilbadm_err(gettext("cannot add %s to %s: %s"),
383*10946SSangeeta.Misra@Sun.COM 				    buf, sgp->sg_name, ilb_errstr(rclib));
384*10946SSangeeta.Misra@Sun.COM 				/* if we created the SG, we bail out */
385*10946SSangeeta.Misra@Sun.COM 				if (cmd == cmd_create_sg)
386*10946SSangeeta.Misra@Sun.COM 					return (rc);
387*10946SSangeeta.Misra@Sun.COM 			}
388*10946SSangeeta.Misra@Sun.COM 		} else {
389*10946SSangeeta.Misra@Sun.COM 			assert(cmd == cmd_rem_srv);
390*10946SSangeeta.Misra@Sun.COM 			rclib = ilb_rem_server_from_group(h, sgp->sg_name,
391*10946SSangeeta.Misra@Sun.COM 			    srv);
392*10946SSangeeta.Misra@Sun.COM 			/* if we fail, we tell user and continue */
393*10946SSangeeta.Misra@Sun.COM 			if (rclib != ILB_STATUS_OK) {
394*10946SSangeeta.Misra@Sun.COM 				rc = ILBADM_LIBERR;
395*10946SSangeeta.Misra@Sun.COM 				ilbadm_err(
396*10946SSangeeta.Misra@Sun.COM 				    gettext("cannot remove %s from %s: %s"),
397*10946SSangeeta.Misra@Sun.COM 				    srv->sd_srvID, sgp->sg_name,
398*10946SSangeeta.Misra@Sun.COM 				    ilb_errstr(rclib));
399*10946SSangeeta.Misra@Sun.COM 			}
400*10946SSangeeta.Misra@Sun.COM 		}
401*10946SSangeeta.Misra@Sun.COM 
402*10946SSangeeta.Misra@Sun.COM 		/*
403*10946SSangeeta.Misra@Sun.COM 		 * list_next returns NULL instead of cycling back to head
404*10946SSangeeta.Misra@Sun.COM 		 * so we don't have to check for list_head explicitly.
405*10946SSangeeta.Misra@Sun.COM 		 */
406*10946SSangeeta.Misra@Sun.COM 		sn = list_next(&sgp->sg_serv_list, sn);
407*10946SSangeeta.Misra@Sun.COM 	};
408*10946SSangeeta.Misra@Sun.COM 
409*10946SSangeeta.Misra@Sun.COM 	return (rc);
410*10946SSangeeta.Misra@Sun.COM }
411*10946SSangeeta.Misra@Sun.COM 
412*10946SSangeeta.Misra@Sun.COM static void
i_ilbadm_alloc_sgroup(ilbadm_sgroup_t ** sgp)413*10946SSangeeta.Misra@Sun.COM i_ilbadm_alloc_sgroup(ilbadm_sgroup_t **sgp)
414*10946SSangeeta.Misra@Sun.COM {
415*10946SSangeeta.Misra@Sun.COM 	ilbadm_sgroup_t	*sg;
416*10946SSangeeta.Misra@Sun.COM 
417*10946SSangeeta.Misra@Sun.COM 	*sgp = sg = (ilbadm_sgroup_t *)calloc(sizeof (*sg), 1);
418*10946SSangeeta.Misra@Sun.COM 	if (sg == NULL)
419*10946SSangeeta.Misra@Sun.COM 		return;
420*10946SSangeeta.Misra@Sun.COM 	list_create(&sg->sg_serv_list, sizeof (ilbadm_servnode_t),
421*10946SSangeeta.Misra@Sun.COM 	    offsetof(ilbadm_servnode_t, s_link));
422*10946SSangeeta.Misra@Sun.COM }
423*10946SSangeeta.Misra@Sun.COM 
424*10946SSangeeta.Misra@Sun.COM static void
i_ilbadm_free_sgroup(ilbadm_sgroup_t * sg)425*10946SSangeeta.Misra@Sun.COM i_ilbadm_free_sgroup(ilbadm_sgroup_t *sg)
426*10946SSangeeta.Misra@Sun.COM {
427*10946SSangeeta.Misra@Sun.COM 	ilbadm_servnode_t	*s;
428*10946SSangeeta.Misra@Sun.COM 
429*10946SSangeeta.Misra@Sun.COM 	while ((s = list_remove_head(&sg->sg_serv_list)) != NULL)
430*10946SSangeeta.Misra@Sun.COM 		free(s);
431*10946SSangeeta.Misra@Sun.COM 
432*10946SSangeeta.Misra@Sun.COM 	list_destroy(&sg->sg_serv_list);
433*10946SSangeeta.Misra@Sun.COM }
434*10946SSangeeta.Misra@Sun.COM 
435*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_create_servergroup(int argc,char * argv[])436*10946SSangeeta.Misra@Sun.COM ilbadm_create_servergroup(int argc, char *argv[])
437*10946SSangeeta.Misra@Sun.COM {
438*10946SSangeeta.Misra@Sun.COM 	ilb_handle_t	h = ILB_INVALID_HANDLE;
439*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rclib = ILB_STATUS_OK;
440*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t	rc = ILBADM_OK;
441*10946SSangeeta.Misra@Sun.COM 	ilbadm_sgroup_t	*sg;
442*10946SSangeeta.Misra@Sun.COM 	int		c;
443*10946SSangeeta.Misra@Sun.COM 	int		flags = 0;
444*10946SSangeeta.Misra@Sun.COM 
445*10946SSangeeta.Misra@Sun.COM 	i_ilbadm_alloc_sgroup(&sg);
446*10946SSangeeta.Misra@Sun.COM 
447*10946SSangeeta.Misra@Sun.COM 	while ((c = getopt(argc, argv, ":s:")) != -1) {
448*10946SSangeeta.Misra@Sun.COM 		switch ((char)c) {
449*10946SSangeeta.Misra@Sun.COM 		case 's':
450*10946SSangeeta.Misra@Sun.COM 			rc = i_parse_servrange_list(optarg, sg);
451*10946SSangeeta.Misra@Sun.COM 			break;
452*10946SSangeeta.Misra@Sun.COM 		case ':':
453*10946SSangeeta.Misra@Sun.COM 			ilbadm_err(gettext("missing option-argument for"
454*10946SSangeeta.Misra@Sun.COM 			    " %c"), (char)optopt);
455*10946SSangeeta.Misra@Sun.COM 			rc = ILBADM_LIBERR;
456*10946SSangeeta.Misra@Sun.COM 			break;
457*10946SSangeeta.Misra@Sun.COM 		case '?':
458*10946SSangeeta.Misra@Sun.COM 		default:
459*10946SSangeeta.Misra@Sun.COM 			unknown_opt(argv, optind-1);
460*10946SSangeeta.Misra@Sun.COM 			/* not reached */
461*10946SSangeeta.Misra@Sun.COM 			break;
462*10946SSangeeta.Misra@Sun.COM 		}
463*10946SSangeeta.Misra@Sun.COM 
464*10946SSangeeta.Misra@Sun.COM 		if (rc != ILBADM_OK)
465*10946SSangeeta.Misra@Sun.COM 			goto out;
466*10946SSangeeta.Misra@Sun.COM 	}
467*10946SSangeeta.Misra@Sun.COM 
468*10946SSangeeta.Misra@Sun.COM 	if (optind >= argc) {
469*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(gettext("missing mandatory arguments - please refer"
470*10946SSangeeta.Misra@Sun.COM 		    " to 'create-servergroup' subcommand"
471*10946SSangeeta.Misra@Sun.COM 		    "  description in ilbadm(1M)"));
472*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
473*10946SSangeeta.Misra@Sun.COM 		goto out;
474*10946SSangeeta.Misra@Sun.COM 	}
475*10946SSangeeta.Misra@Sun.COM 
476*10946SSangeeta.Misra@Sun.COM 	if (strlen(argv[optind]) > ILB_SGNAME_SZ - 1) {
477*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(gettext("servergroup name %s is too long -"
478*10946SSangeeta.Misra@Sun.COM 		    " must not exceed %d chars"), argv[optind],
479*10946SSangeeta.Misra@Sun.COM 		    ILB_SGNAME_SZ - 1);
480*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
481*10946SSangeeta.Misra@Sun.COM 		goto out;
482*10946SSangeeta.Misra@Sun.COM 	}
483*10946SSangeeta.Misra@Sun.COM 
484*10946SSangeeta.Misra@Sun.COM 	sg->sg_name = argv[optind];
485*10946SSangeeta.Misra@Sun.COM 
486*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_open(&h);
487*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK)
488*10946SSangeeta.Misra@Sun.COM 		goto out;
489*10946SSangeeta.Misra@Sun.COM 
490*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_create_servergroup(h, sg->sg_name);
491*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK)
492*10946SSangeeta.Misra@Sun.COM 		goto out;
493*10946SSangeeta.Misra@Sun.COM 
494*10946SSangeeta.Misra@Sun.COM 	/* we create a servergroup with all servers enabled */
495*10946SSangeeta.Misra@Sun.COM 	ILB_SET_ENABLED(flags);
496*10946SSangeeta.Misra@Sun.COM 	rc = i_mod_sg(h, sg, cmd_create_sg, flags);
497*10946SSangeeta.Misra@Sun.COM 
498*10946SSangeeta.Misra@Sun.COM 	if (rc != ILBADM_OK)
499*10946SSangeeta.Misra@Sun.COM 		(void) ilb_destroy_servergroup(h, sg->sg_name);
500*10946SSangeeta.Misra@Sun.COM 
501*10946SSangeeta.Misra@Sun.COM out:
502*10946SSangeeta.Misra@Sun.COM 	i_ilbadm_free_sgroup(sg);
503*10946SSangeeta.Misra@Sun.COM 	if (h != ILB_INVALID_HANDLE)
504*10946SSangeeta.Misra@Sun.COM 		(void) ilb_close(h);
505*10946SSangeeta.Misra@Sun.COM 
506*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK) {
507*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilb_errstr(rclib));
508*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
509*10946SSangeeta.Misra@Sun.COM 	}
510*10946SSangeeta.Misra@Sun.COM 	if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
511*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilbadm_errstr(rc));
512*10946SSangeeta.Misra@Sun.COM 
513*10946SSangeeta.Misra@Sun.COM 	return (rc);
514*10946SSangeeta.Misra@Sun.COM }
515*10946SSangeeta.Misra@Sun.COM 
516*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_add_server_to_group(int argc,char ** argv)517*10946SSangeeta.Misra@Sun.COM ilbadm_add_server_to_group(int argc, char **argv)
518*10946SSangeeta.Misra@Sun.COM {
519*10946SSangeeta.Misra@Sun.COM 	ilb_handle_t	h = ILB_INVALID_HANDLE;
520*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rclib = ILB_STATUS_OK;
521*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t	rc = ILBADM_OK;
522*10946SSangeeta.Misra@Sun.COM 	ilbadm_sgroup_t	*sg;
523*10946SSangeeta.Misra@Sun.COM 	int		c;
524*10946SSangeeta.Misra@Sun.COM 	int		flags = 0;
525*10946SSangeeta.Misra@Sun.COM 
526*10946SSangeeta.Misra@Sun.COM 	i_ilbadm_alloc_sgroup(&sg);
527*10946SSangeeta.Misra@Sun.COM 
528*10946SSangeeta.Misra@Sun.COM 	while ((c = getopt(argc, argv, ":s:")) != -1) {
529*10946SSangeeta.Misra@Sun.COM 		switch ((char)c) {
530*10946SSangeeta.Misra@Sun.COM 		case 's':
531*10946SSangeeta.Misra@Sun.COM 			rc = i_parse_servrange_list(optarg, sg);
532*10946SSangeeta.Misra@Sun.COM 			break;
533*10946SSangeeta.Misra@Sun.COM 		case ':':
534*10946SSangeeta.Misra@Sun.COM 			ilbadm_err(gettext("missing option-argument for"
535*10946SSangeeta.Misra@Sun.COM 			    " %c"), (char)optopt);
536*10946SSangeeta.Misra@Sun.COM 			rc = ILBADM_LIBERR;
537*10946SSangeeta.Misra@Sun.COM 			break;
538*10946SSangeeta.Misra@Sun.COM 		case '?':
539*10946SSangeeta.Misra@Sun.COM 		default: unknown_opt(argv, optind-1);
540*10946SSangeeta.Misra@Sun.COM 			/* not reached */
541*10946SSangeeta.Misra@Sun.COM 			break;
542*10946SSangeeta.Misra@Sun.COM 		}
543*10946SSangeeta.Misra@Sun.COM 
544*10946SSangeeta.Misra@Sun.COM 		if (rc != ILBADM_OK)
545*10946SSangeeta.Misra@Sun.COM 			goto out;
546*10946SSangeeta.Misra@Sun.COM 	}
547*10946SSangeeta.Misra@Sun.COM 
548*10946SSangeeta.Misra@Sun.COM 	if (optind >= argc) {
549*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(gettext("missing mandatory arguments - please refer"
550*10946SSangeeta.Misra@Sun.COM 		    " to 'add-server' subcommand description in ilbadm(1M)"));
551*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
552*10946SSangeeta.Misra@Sun.COM 		goto out;
553*10946SSangeeta.Misra@Sun.COM 	}
554*10946SSangeeta.Misra@Sun.COM 
555*10946SSangeeta.Misra@Sun.COM 	sg->sg_name = argv[optind];
556*10946SSangeeta.Misra@Sun.COM 
557*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_open(&h);
558*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK)
559*10946SSangeeta.Misra@Sun.COM 		goto out;
560*10946SSangeeta.Misra@Sun.COM 
561*10946SSangeeta.Misra@Sun.COM 	/* A server is added enabled */
562*10946SSangeeta.Misra@Sun.COM 	ILB_SET_ENABLED(flags);
563*10946SSangeeta.Misra@Sun.COM 	rc = i_mod_sg(h, sg, cmd_add_srv, flags);
564*10946SSangeeta.Misra@Sun.COM out:
565*10946SSangeeta.Misra@Sun.COM 	i_ilbadm_free_sgroup(sg);
566*10946SSangeeta.Misra@Sun.COM 	if (h != ILB_INVALID_HANDLE)
567*10946SSangeeta.Misra@Sun.COM 		(void) ilb_close(h);
568*10946SSangeeta.Misra@Sun.COM 
569*10946SSangeeta.Misra@Sun.COM 	if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
570*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilbadm_errstr(rc));
571*10946SSangeeta.Misra@Sun.COM 	return (rc);
572*10946SSangeeta.Misra@Sun.COM }
573*10946SSangeeta.Misra@Sun.COM 
574*10946SSangeeta.Misra@Sun.COM /* ARGSUSED */
575*10946SSangeeta.Misra@Sun.COM static ilbadm_status_t
ilbadm_Xable_server(int argc,char * argv[],ilbadm_cmd_t cmd)576*10946SSangeeta.Misra@Sun.COM ilbadm_Xable_server(int argc, char *argv[], ilbadm_cmd_t cmd)
577*10946SSangeeta.Misra@Sun.COM {
578*10946SSangeeta.Misra@Sun.COM 	ilb_handle_t		h = ILB_INVALID_HANDLE;
579*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t		rc = ILBADM_OK;
580*10946SSangeeta.Misra@Sun.COM 	ilb_status_t		rclib = ILB_STATUS_OK;
581*10946SSangeeta.Misra@Sun.COM 	int			i;
582*10946SSangeeta.Misra@Sun.COM 
583*10946SSangeeta.Misra@Sun.COM 	if (argc < 2) {
584*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(gettext("missing required argument"
585*10946SSangeeta.Misra@Sun.COM 		    " (server specification)"));
586*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
587*10946SSangeeta.Misra@Sun.COM 		goto out;
588*10946SSangeeta.Misra@Sun.COM 	}
589*10946SSangeeta.Misra@Sun.COM 
590*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_open(&h);
591*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK)
592*10946SSangeeta.Misra@Sun.COM 		goto out;
593*10946SSangeeta.Misra@Sun.COM 
594*10946SSangeeta.Misra@Sun.COM 	/* enable-server and disable-server only accepts serverids */
595*10946SSangeeta.Misra@Sun.COM 	for (i = 1; i < argc && rclib == ILB_STATUS_OK; i++) {
596*10946SSangeeta.Misra@Sun.COM 		ilb_server_data_t	srv;
597*10946SSangeeta.Misra@Sun.COM 
598*10946SSangeeta.Misra@Sun.COM 		if (argv[i][0] != ILB_SRVID_PREFIX) {
599*10946SSangeeta.Misra@Sun.COM 			rc = ILBADM_INVAL_SRVID;
600*10946SSangeeta.Misra@Sun.COM 			goto out;
601*10946SSangeeta.Misra@Sun.COM 		}
602*10946SSangeeta.Misra@Sun.COM 
603*10946SSangeeta.Misra@Sun.COM 		bzero(&srv, sizeof (srv));
604*10946SSangeeta.Misra@Sun.COM 		/* to do: check length */
605*10946SSangeeta.Misra@Sun.COM 		(void) strlcpy(srv.sd_srvID, argv[i], sizeof (srv.sd_srvID));
606*10946SSangeeta.Misra@Sun.COM 		switch (cmd) {
607*10946SSangeeta.Misra@Sun.COM 		case cmd_enable_server:
608*10946SSangeeta.Misra@Sun.COM 			rclib = ilb_enable_server(h, &srv, NULL);
609*10946SSangeeta.Misra@Sun.COM 			break;
610*10946SSangeeta.Misra@Sun.COM 		case cmd_disable_server:
611*10946SSangeeta.Misra@Sun.COM 			rclib = ilb_disable_server(h, &srv, NULL);
612*10946SSangeeta.Misra@Sun.COM 			break;
613*10946SSangeeta.Misra@Sun.COM 		}
614*10946SSangeeta.Misra@Sun.COM 
615*10946SSangeeta.Misra@Sun.COM 		/* if we can't find a given server ID, just plough on */
616*10946SSangeeta.Misra@Sun.COM 		if (rclib == ILB_STATUS_ENOENT) {
617*10946SSangeeta.Misra@Sun.COM 			const char *msg = ilb_errstr(rclib);
618*10946SSangeeta.Misra@Sun.COM 
619*10946SSangeeta.Misra@Sun.COM 			rc = ILBADM_LIBERR;
620*10946SSangeeta.Misra@Sun.COM 			ilbadm_err("%s: %s", msg, argv[i]);
621*10946SSangeeta.Misra@Sun.COM 			rclib = ILB_STATUS_OK;
622*10946SSangeeta.Misra@Sun.COM 			continue;
623*10946SSangeeta.Misra@Sun.COM 		}
624*10946SSangeeta.Misra@Sun.COM 		if (rclib != ILB_STATUS_OK)
625*10946SSangeeta.Misra@Sun.COM 			break;
626*10946SSangeeta.Misra@Sun.COM 	}
627*10946SSangeeta.Misra@Sun.COM out:
628*10946SSangeeta.Misra@Sun.COM 	if (h != ILB_INVALID_HANDLE)
629*10946SSangeeta.Misra@Sun.COM 		(void) ilb_close(h);
630*10946SSangeeta.Misra@Sun.COM 
631*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK) {
632*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilb_errstr(rclib));
633*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
634*10946SSangeeta.Misra@Sun.COM 	}
635*10946SSangeeta.Misra@Sun.COM 
636*10946SSangeeta.Misra@Sun.COM 	if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
637*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilbadm_errstr(rc));
638*10946SSangeeta.Misra@Sun.COM 	return (rc);
639*10946SSangeeta.Misra@Sun.COM }
640*10946SSangeeta.Misra@Sun.COM 
641*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_disable_server(int argc,char * argv[])642*10946SSangeeta.Misra@Sun.COM ilbadm_disable_server(int argc, char *argv[])
643*10946SSangeeta.Misra@Sun.COM {
644*10946SSangeeta.Misra@Sun.COM 	return (ilbadm_Xable_server(argc, argv, cmd_disable_server));
645*10946SSangeeta.Misra@Sun.COM }
646*10946SSangeeta.Misra@Sun.COM 
647*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_enable_server(int argc,char * argv[])648*10946SSangeeta.Misra@Sun.COM ilbadm_enable_server(int argc, char *argv[])
649*10946SSangeeta.Misra@Sun.COM {
650*10946SSangeeta.Misra@Sun.COM 	return (ilbadm_Xable_server(argc, argv, cmd_enable_server));
651*10946SSangeeta.Misra@Sun.COM }
652*10946SSangeeta.Misra@Sun.COM 
653*10946SSangeeta.Misra@Sun.COM /* ARGSUSED */
654*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_rem_server_from_group(int argc,char * argv[])655*10946SSangeeta.Misra@Sun.COM ilbadm_rem_server_from_group(int argc, char *argv[])
656*10946SSangeeta.Misra@Sun.COM {
657*10946SSangeeta.Misra@Sun.COM 	ilb_handle_t	h = ILB_INVALID_HANDLE;
658*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rclib = ILB_STATUS_OK;
659*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t	rc = ILBADM_OK;
660*10946SSangeeta.Misra@Sun.COM 	ilbadm_sgroup_t	*sg;
661*10946SSangeeta.Misra@Sun.COM 	int		c;
662*10946SSangeeta.Misra@Sun.COM 
663*10946SSangeeta.Misra@Sun.COM 	i_ilbadm_alloc_sgroup(&sg);
664*10946SSangeeta.Misra@Sun.COM 
665*10946SSangeeta.Misra@Sun.COM 	while ((c = getopt(argc, argv, ":s:")) != -1) {
666*10946SSangeeta.Misra@Sun.COM 		switch ((char)c) {
667*10946SSangeeta.Misra@Sun.COM 		case 's':
668*10946SSangeeta.Misra@Sun.COM 			rc = i_parse_serverIDs(optarg, sg);
669*10946SSangeeta.Misra@Sun.COM 			break;
670*10946SSangeeta.Misra@Sun.COM 		case ':':
671*10946SSangeeta.Misra@Sun.COM 			ilbadm_err(gettext("missing option-argument for"
672*10946SSangeeta.Misra@Sun.COM 			    " %c"), (char)optopt);
673*10946SSangeeta.Misra@Sun.COM 			rc = ILBADM_LIBERR;
674*10946SSangeeta.Misra@Sun.COM 			break;
675*10946SSangeeta.Misra@Sun.COM 		case '?':
676*10946SSangeeta.Misra@Sun.COM 		default: unknown_opt(argv, optind-1);
677*10946SSangeeta.Misra@Sun.COM 			/* not reached */
678*10946SSangeeta.Misra@Sun.COM 			break;
679*10946SSangeeta.Misra@Sun.COM 		}
680*10946SSangeeta.Misra@Sun.COM 		if (rc != ILBADM_OK)
681*10946SSangeeta.Misra@Sun.COM 			goto out;
682*10946SSangeeta.Misra@Sun.COM 	}
683*10946SSangeeta.Misra@Sun.COM 
684*10946SSangeeta.Misra@Sun.COM 	/* we need servergroup name and at least one serverID to remove */
685*10946SSangeeta.Misra@Sun.COM 	if (optind >= argc || sg->sg_count == 0) {
686*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_ENOOPTION;
687*10946SSangeeta.Misra@Sun.COM 		goto out;
688*10946SSangeeta.Misra@Sun.COM 	}
689*10946SSangeeta.Misra@Sun.COM 
690*10946SSangeeta.Misra@Sun.COM 	sg->sg_name = argv[optind];
691*10946SSangeeta.Misra@Sun.COM 
692*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_open(&h);
693*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK)
694*10946SSangeeta.Misra@Sun.COM 		goto out;
695*10946SSangeeta.Misra@Sun.COM 
696*10946SSangeeta.Misra@Sun.COM 	rc = i_mod_sg(h, sg, cmd_rem_srv, 0);
697*10946SSangeeta.Misra@Sun.COM out:
698*10946SSangeeta.Misra@Sun.COM 	i_ilbadm_free_sgroup(sg);
699*10946SSangeeta.Misra@Sun.COM 
700*10946SSangeeta.Misra@Sun.COM 	if (h != ILB_INVALID_HANDLE)
701*10946SSangeeta.Misra@Sun.COM 		(void) ilb_close(h);
702*10946SSangeeta.Misra@Sun.COM 	if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
703*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilbadm_errstr(rc));
704*10946SSangeeta.Misra@Sun.COM 	return (rc);
705*10946SSangeeta.Misra@Sun.COM }
706*10946SSangeeta.Misra@Sun.COM 
707*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_destroy_servergroup(int argc,char * argv[])708*10946SSangeeta.Misra@Sun.COM ilbadm_destroy_servergroup(int argc, char *argv[])
709*10946SSangeeta.Misra@Sun.COM {
710*10946SSangeeta.Misra@Sun.COM 	ilb_handle_t	h = ILB_INVALID_HANDLE;
711*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rclib = ILB_STATUS_OK;
712*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t	rc = ILBADM_OK;
713*10946SSangeeta.Misra@Sun.COM 	char		*sgname;
714*10946SSangeeta.Misra@Sun.COM 
715*10946SSangeeta.Misra@Sun.COM 	if (argc != 2) {
716*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(gettext("usage:ilbadm"
717*10946SSangeeta.Misra@Sun.COM 		    " delete-servergroup groupname"));
718*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
719*10946SSangeeta.Misra@Sun.COM 		goto out;
720*10946SSangeeta.Misra@Sun.COM 	}
721*10946SSangeeta.Misra@Sun.COM 
722*10946SSangeeta.Misra@Sun.COM 	sgname = argv[1];
723*10946SSangeeta.Misra@Sun.COM 
724*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_open(&h);
725*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK)
726*10946SSangeeta.Misra@Sun.COM 		goto out;
727*10946SSangeeta.Misra@Sun.COM 
728*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_destroy_servergroup(h, sgname);
729*10946SSangeeta.Misra@Sun.COM out:
730*10946SSangeeta.Misra@Sun.COM 	if (h != ILB_INVALID_HANDLE)
731*10946SSangeeta.Misra@Sun.COM 		(void) ilb_close(h);
732*10946SSangeeta.Misra@Sun.COM 
733*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK) {
734*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilb_errstr(rclib));
735*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
736*10946SSangeeta.Misra@Sun.COM 	}
737*10946SSangeeta.Misra@Sun.COM 
738*10946SSangeeta.Misra@Sun.COM 	return (rc);
739*10946SSangeeta.Misra@Sun.COM }
740*10946SSangeeta.Misra@Sun.COM 
741*10946SSangeeta.Misra@Sun.COM #define	BUFSZ	1024
742*10946SSangeeta.Misra@Sun.COM 
743*10946SSangeeta.Misra@Sun.COM static int
export_srv_spec(ilb_server_data_t * srv,char * buf,const int bufsize)744*10946SSangeeta.Misra@Sun.COM export_srv_spec(ilb_server_data_t *srv, char *buf, const int bufsize)
745*10946SSangeeta.Misra@Sun.COM {
746*10946SSangeeta.Misra@Sun.COM 	int	len = 0, bufsz = (int)bufsize;
747*10946SSangeeta.Misra@Sun.COM 
748*10946SSangeeta.Misra@Sun.COM 	ip2str(&srv->sd_addr, buf, bufsz, 0);
749*10946SSangeeta.Misra@Sun.COM 
750*10946SSangeeta.Misra@Sun.COM 	len += strlen(buf);
751*10946SSangeeta.Misra@Sun.COM 	bufsz -= len;
752*10946SSangeeta.Misra@Sun.COM 
753*10946SSangeeta.Misra@Sun.COM 	if (srv->sd_minport != 0) {
754*10946SSangeeta.Misra@Sun.COM 		in_port_t	h_min, h_max;
755*10946SSangeeta.Misra@Sun.COM 		int		inc;
756*10946SSangeeta.Misra@Sun.COM 
757*10946SSangeeta.Misra@Sun.COM 		h_min = ntohs(srv->sd_minport);
758*10946SSangeeta.Misra@Sun.COM 		h_max = ntohs(srv->sd_maxport);
759*10946SSangeeta.Misra@Sun.COM 
760*10946SSangeeta.Misra@Sun.COM 		/* to do: if service name was given, print that, not number */
761*10946SSangeeta.Misra@Sun.COM 		if (h_max <= h_min)
762*10946SSangeeta.Misra@Sun.COM 			inc = snprintf(buf+len, bufsz, ":%d", h_min);
763*10946SSangeeta.Misra@Sun.COM 		else
764*10946SSangeeta.Misra@Sun.COM 			inc = snprintf(buf+len, bufsz, ":%d-%d", h_min, h_max);
765*10946SSangeeta.Misra@Sun.COM 
766*10946SSangeeta.Misra@Sun.COM 		if (inc > bufsz) /* too little space */
767*10946SSangeeta.Misra@Sun.COM 			return (-1);
768*10946SSangeeta.Misra@Sun.COM 		len += inc;
769*10946SSangeeta.Misra@Sun.COM 	}
770*10946SSangeeta.Misra@Sun.COM 
771*10946SSangeeta.Misra@Sun.COM 	return (len);
772*10946SSangeeta.Misra@Sun.COM }
773*10946SSangeeta.Misra@Sun.COM 
774*10946SSangeeta.Misra@Sun.COM 
775*10946SSangeeta.Misra@Sun.COM /*
776*10946SSangeeta.Misra@Sun.COM  * this is called by ilb_walk_servers(), therefore we return ilb_status_t
777*10946SSangeeta.Misra@Sun.COM  * not ilbadm_status, and retain an unused function argument
778*10946SSangeeta.Misra@Sun.COM  */
779*10946SSangeeta.Misra@Sun.COM /* ARGSUSED */
780*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilbadm_export_a_srv(ilb_handle_t h,ilb_server_data_t * srv,const char * sgname,void * arg)781*10946SSangeeta.Misra@Sun.COM ilbadm_export_a_srv(ilb_handle_t h, ilb_server_data_t *srv, const char *sgname,
782*10946SSangeeta.Misra@Sun.COM     void *arg)
783*10946SSangeeta.Misra@Sun.COM {
784*10946SSangeeta.Misra@Sun.COM 	sg_export_arg_t	*larg = (sg_export_arg_t *)arg;
785*10946SSangeeta.Misra@Sun.COM 	FILE		*fp = larg->fp;
786*10946SSangeeta.Misra@Sun.COM 	char		linebuf[BUFSZ]; /* XXXms make that dynamic */
787*10946SSangeeta.Misra@Sun.COM 	int		sz = BUFSZ;
788*10946SSangeeta.Misra@Sun.COM 
789*10946SSangeeta.Misra@Sun.COM 	if (export_srv_spec(srv, linebuf, sz) == -1)
790*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_OK);
791*10946SSangeeta.Misra@Sun.COM 
792*10946SSangeeta.Misra@Sun.COM 	(void) fprintf(fp, "add-server -s server=");
793*10946SSangeeta.Misra@Sun.COM 
794*10946SSangeeta.Misra@Sun.COM 	(void) fprintf(fp, "%s %s\n", linebuf, sgname);
795*10946SSangeeta.Misra@Sun.COM 	return (ILB_STATUS_OK);
796*10946SSangeeta.Misra@Sun.COM }
797*10946SSangeeta.Misra@Sun.COM 
798*10946SSangeeta.Misra@Sun.COM ilb_status_t
ilbadm_export_sg(ilb_handle_t h,ilb_sg_data_t * sg,void * arg)799*10946SSangeeta.Misra@Sun.COM ilbadm_export_sg(ilb_handle_t h, ilb_sg_data_t *sg, void *arg)
800*10946SSangeeta.Misra@Sun.COM {
801*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rc = ILB_STATUS_OK;
802*10946SSangeeta.Misra@Sun.COM 	sg_export_arg_t	*larg = (sg_export_arg_t *)arg;
803*10946SSangeeta.Misra@Sun.COM 	FILE		*fp = larg->fp;
804*10946SSangeeta.Misra@Sun.COM 
805*10946SSangeeta.Misra@Sun.COM 	(void) fprintf(fp, "create-servergroup %s\n", sg->sgd_name);
806*10946SSangeeta.Misra@Sun.COM 	if (sg->sgd_srvcount == 0)
807*10946SSangeeta.Misra@Sun.COM 		return (ILB_STATUS_OK);
808*10946SSangeeta.Misra@Sun.COM 
809*10946SSangeeta.Misra@Sun.COM 	rc = ilb_walk_servers(h, ilbadm_export_a_srv, sg->sgd_name, arg);
810*10946SSangeeta.Misra@Sun.COM 	if (rc != ILB_STATUS_OK)
811*10946SSangeeta.Misra@Sun.COM 		goto out;
812*10946SSangeeta.Misra@Sun.COM 
813*10946SSangeeta.Misra@Sun.COM 	if (fflush(fp) == EOF)
814*10946SSangeeta.Misra@Sun.COM 		rc = ILB_STATUS_WRITE;
815*10946SSangeeta.Misra@Sun.COM 
816*10946SSangeeta.Misra@Sun.COM out:
817*10946SSangeeta.Misra@Sun.COM 	return (rc);
818*10946SSangeeta.Misra@Sun.COM }
819*10946SSangeeta.Misra@Sun.COM 
820*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_export_servergroups(ilb_handle_t h,FILE * fp)821*10946SSangeeta.Misra@Sun.COM ilbadm_export_servergroups(ilb_handle_t h, FILE *fp)
822*10946SSangeeta.Misra@Sun.COM {
823*10946SSangeeta.Misra@Sun.COM 	ilb_status_t	rclib = ILB_STATUS_OK;
824*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t	rc = ILBADM_OK;
825*10946SSangeeta.Misra@Sun.COM 	sg_export_arg_t	arg;
826*10946SSangeeta.Misra@Sun.COM 
827*10946SSangeeta.Misra@Sun.COM 	arg.fp = fp;
828*10946SSangeeta.Misra@Sun.COM 	arg.sg = NULL;
829*10946SSangeeta.Misra@Sun.COM 
830*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_walk_servergroups(h, ilbadm_export_sg, NULL, (void *)&arg);
831*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK) {
832*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilb_errstr(rclib));
833*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
834*10946SSangeeta.Misra@Sun.COM 	}
835*10946SSangeeta.Misra@Sun.COM 
836*10946SSangeeta.Misra@Sun.COM 	return (rc);
837*10946SSangeeta.Misra@Sun.COM }
838