xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/ilbadm/ilbadm_nat.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 <sys/types.h>
28*10946SSangeeta.Misra@Sun.COM #include <sys/socket.h>
29*10946SSangeeta.Misra@Sun.COM #include <stdlib.h>
30*10946SSangeeta.Misra@Sun.COM #include <stdio.h>
31*10946SSangeeta.Misra@Sun.COM #include <strings.h>
32*10946SSangeeta.Misra@Sun.COM #include <netinet/in.h>
33*10946SSangeeta.Misra@Sun.COM #include <arpa/inet.h>
34*10946SSangeeta.Misra@Sun.COM #include <libilb.h>
35*10946SSangeeta.Misra@Sun.COM #include "ilbadm.h"
36*10946SSangeeta.Misra@Sun.COM 
37*10946SSangeeta.Misra@Sun.COM /*
38*10946SSangeeta.Misra@Sun.COM  * For each iteration through the kernel table, ask for at most NUM_ENTRIES
39*10946SSangeeta.Misra@Sun.COM  * entries to be returned.
40*10946SSangeeta.Misra@Sun.COM  */
41*10946SSangeeta.Misra@Sun.COM #define	NUM_ENTRIES	500
42*10946SSangeeta.Misra@Sun.COM 
43*10946SSangeeta.Misra@Sun.COM static void
print_nat_info(ilb_nat_info_t * info)44*10946SSangeeta.Misra@Sun.COM print_nat_info(ilb_nat_info_t *info)
45*10946SSangeeta.Misra@Sun.COM {
46*10946SSangeeta.Misra@Sun.COM 	char *tmp;
47*10946SSangeeta.Misra@Sun.COM 	ipaddr_t addr_v4;
48*10946SSangeeta.Misra@Sun.COM 	char addr[INET6_ADDRSTRLEN];
49*10946SSangeeta.Misra@Sun.COM 
50*10946SSangeeta.Misra@Sun.COM 	if (info->nat_proto == IPPROTO_TCP)
51*10946SSangeeta.Misra@Sun.COM 		tmp = "TCP";
52*10946SSangeeta.Misra@Sun.COM 	else if (info->nat_proto == IPPROTO_UDP)
53*10946SSangeeta.Misra@Sun.COM 		tmp = "UDP";
54*10946SSangeeta.Misra@Sun.COM 	else
55*10946SSangeeta.Misra@Sun.COM 		tmp = "Unknown";
56*10946SSangeeta.Misra@Sun.COM 	(void) printf("%4s: ", tmp);
57*10946SSangeeta.Misra@Sun.COM 
58*10946SSangeeta.Misra@Sun.COM 	if (IN6_IS_ADDR_V4MAPPED(&info->nat_out_global)) {
59*10946SSangeeta.Misra@Sun.COM 		IN6_V4MAPPED_TO_IPADDR(&info->nat_out_global, addr_v4);
60*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s.%d > ", inet_ntop(AF_INET, &addr_v4, addr,
61*10946SSangeeta.Misra@Sun.COM 		    INET6_ADDRSTRLEN), ntohs(info->nat_out_global_port));
62*10946SSangeeta.Misra@Sun.COM 		IN6_V4MAPPED_TO_IPADDR(&info->nat_in_global, addr_v4);
63*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s.%d >>> ", inet_ntop(AF_INET, &addr_v4, addr,
64*10946SSangeeta.Misra@Sun.COM 		    INET6_ADDRSTRLEN), ntohs(info->nat_in_global_port));
65*10946SSangeeta.Misra@Sun.COM 
66*10946SSangeeta.Misra@Sun.COM 		IN6_V4MAPPED_TO_IPADDR(&info->nat_out_local, addr_v4);
67*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s.%d > ", inet_ntop(AF_INET, &addr_v4, addr,
68*10946SSangeeta.Misra@Sun.COM 		    INET6_ADDRSTRLEN), ntohs(info->nat_out_local_port));
69*10946SSangeeta.Misra@Sun.COM 		IN6_V4MAPPED_TO_IPADDR(&info->nat_in_local, addr_v4);
70*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s.%d\n", inet_ntop(AF_INET, &addr_v4, addr,
71*10946SSangeeta.Misra@Sun.COM 		    INET6_ADDRSTRLEN), ntohs(info->nat_in_local_port));
72*10946SSangeeta.Misra@Sun.COM 	} else {
73*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s.%d > ", inet_ntop(AF_INET6,
74*10946SSangeeta.Misra@Sun.COM 		    &info->nat_out_global, addr, INET6_ADDRSTRLEN),
75*10946SSangeeta.Misra@Sun.COM 		    ntohs(info->nat_out_global_port));
76*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s.%d >>> ", inet_ntop(AF_INET6,
77*10946SSangeeta.Misra@Sun.COM 		    &info->nat_in_global, addr, INET6_ADDRSTRLEN),
78*10946SSangeeta.Misra@Sun.COM 		    ntohs(info->nat_in_global_port));
79*10946SSangeeta.Misra@Sun.COM 
80*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s.%d > ", inet_ntop(AF_INET6,
81*10946SSangeeta.Misra@Sun.COM 		    &info->nat_out_local, addr, INET6_ADDRSTRLEN),
82*10946SSangeeta.Misra@Sun.COM 		    ntohs(info->nat_out_local_port));
83*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s.%d\n", inet_ntop(AF_INET6,
84*10946SSangeeta.Misra@Sun.COM 		    &info->nat_in_local, addr, INET6_ADDRSTRLEN),
85*10946SSangeeta.Misra@Sun.COM 		    ntohs(info->nat_in_local_port));
86*10946SSangeeta.Misra@Sun.COM 	}
87*10946SSangeeta.Misra@Sun.COM }
88*10946SSangeeta.Misra@Sun.COM 
89*10946SSangeeta.Misra@Sun.COM static void
print_persist_info(ilb_persist_info_t * info)90*10946SSangeeta.Misra@Sun.COM print_persist_info(ilb_persist_info_t *info)
91*10946SSangeeta.Misra@Sun.COM {
92*10946SSangeeta.Misra@Sun.COM 	char addr[INET6_ADDRSTRLEN];
93*10946SSangeeta.Misra@Sun.COM 
94*10946SSangeeta.Misra@Sun.COM 	(void) printf("%s: ", info->persist_rule_name);
95*10946SSangeeta.Misra@Sun.COM 	if (IN6_IS_ADDR_V4MAPPED(&info->persist_req_addr)) {
96*10946SSangeeta.Misra@Sun.COM 		ipaddr_t addr_v4;
97*10946SSangeeta.Misra@Sun.COM 
98*10946SSangeeta.Misra@Sun.COM 		IN6_V4MAPPED_TO_IPADDR(&info->persist_req_addr, addr_v4);
99*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s --> ", inet_ntop(AF_INET, &addr_v4, addr,
100*10946SSangeeta.Misra@Sun.COM 		    INET6_ADDRSTRLEN));
101*10946SSangeeta.Misra@Sun.COM 		IN6_V4MAPPED_TO_IPADDR(&info->persist_srv_addr, addr_v4);
102*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s\n", inet_ntop(AF_INET, &addr_v4, addr,
103*10946SSangeeta.Misra@Sun.COM 		    INET6_ADDRSTRLEN));
104*10946SSangeeta.Misra@Sun.COM 	} else {
105*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s --> ", inet_ntop(AF_INET6,
106*10946SSangeeta.Misra@Sun.COM 		    &info->persist_req_addr, addr, INET6_ADDRSTRLEN));
107*10946SSangeeta.Misra@Sun.COM 		(void) printf("%s\n", inet_ntop(AF_INET6,
108*10946SSangeeta.Misra@Sun.COM 		    &info->persist_srv_addr, addr, INET6_ADDRSTRLEN));
109*10946SSangeeta.Misra@Sun.COM 	}
110*10946SSangeeta.Misra@Sun.COM }
111*10946SSangeeta.Misra@Sun.COM 
112*10946SSangeeta.Misra@Sun.COM /* Tell ilbadm_show_info() which table to show. */
113*10946SSangeeta.Misra@Sun.COM enum which_tbl {
114*10946SSangeeta.Misra@Sun.COM 	show_nat = 1,
115*10946SSangeeta.Misra@Sun.COM 	show_persist
116*10946SSangeeta.Misra@Sun.COM };
117*10946SSangeeta.Misra@Sun.COM 
118*10946SSangeeta.Misra@Sun.COM typedef union {
119*10946SSangeeta.Misra@Sun.COM 	ilb_nat_info_t		*nbuf;
120*10946SSangeeta.Misra@Sun.COM 	ilb_persist_info_t	*pbuf;
121*10946SSangeeta.Misra@Sun.COM 	char			*buf;
122*10946SSangeeta.Misra@Sun.COM } show_buf_t;
123*10946SSangeeta.Misra@Sun.COM 
124*10946SSangeeta.Misra@Sun.COM static ilbadm_status_t
ilbadm_show_info(int argc,char * argv[],enum which_tbl tbl)125*10946SSangeeta.Misra@Sun.COM ilbadm_show_info(int argc, char *argv[], enum which_tbl tbl)
126*10946SSangeeta.Misra@Sun.COM {
127*10946SSangeeta.Misra@Sun.COM 	ilb_handle_t		h = ILB_INVALID_HANDLE;
128*10946SSangeeta.Misra@Sun.COM 	show_buf_t		buf;
129*10946SSangeeta.Misra@Sun.COM 	ilb_status_t		rclib = ILB_STATUS_OK;
130*10946SSangeeta.Misra@Sun.COM 	ilbadm_status_t		rc = ILBADM_OK;
131*10946SSangeeta.Misra@Sun.COM 	int32_t			i, num_entries;
132*10946SSangeeta.Misra@Sun.COM 	size_t			num;
133*10946SSangeeta.Misra@Sun.COM 	boolean_t		end;
134*10946SSangeeta.Misra@Sun.COM 	size_t			entry_sz;
135*10946SSangeeta.Misra@Sun.COM 
136*10946SSangeeta.Misra@Sun.COM 	/*
137*10946SSangeeta.Misra@Sun.COM 	 * If the user does not specify a count, return the whole table.
138*10946SSangeeta.Misra@Sun.COM 	 * This requires setting the fourth param to ilb_show_nat/persist()
139*10946SSangeeta.Misra@Sun.COM 	 * end to B_FALSE.  Otherwise, set end to B_TRUE;
140*10946SSangeeta.Misra@Sun.COM 	 */
141*10946SSangeeta.Misra@Sun.COM 
142*10946SSangeeta.Misra@Sun.COM 	switch (argc) {
143*10946SSangeeta.Misra@Sun.COM 	case 1:
144*10946SSangeeta.Misra@Sun.COM 		num_entries = -1;
145*10946SSangeeta.Misra@Sun.COM 		end = B_FALSE;
146*10946SSangeeta.Misra@Sun.COM 		break;
147*10946SSangeeta.Misra@Sun.COM 	case 2:
148*10946SSangeeta.Misra@Sun.COM 		num_entries = atoi(argv[1]);
149*10946SSangeeta.Misra@Sun.COM 		if (num_entries < 1) {
150*10946SSangeeta.Misra@Sun.COM 			rc = ILBADM_EINVAL;
151*10946SSangeeta.Misra@Sun.COM 			goto out;
152*10946SSangeeta.Misra@Sun.COM 		}
153*10946SSangeeta.Misra@Sun.COM 		end = B_TRUE;
154*10946SSangeeta.Misra@Sun.COM 		break;
155*10946SSangeeta.Misra@Sun.COM 	default:
156*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_EINVAL;
157*10946SSangeeta.Misra@Sun.COM 		goto out;
158*10946SSangeeta.Misra@Sun.COM 	}
159*10946SSangeeta.Misra@Sun.COM 
160*10946SSangeeta.Misra@Sun.COM 	if (tbl == show_nat)
161*10946SSangeeta.Misra@Sun.COM 		entry_sz = sizeof (ilb_nat_info_t);
162*10946SSangeeta.Misra@Sun.COM 	else
163*10946SSangeeta.Misra@Sun.COM 		entry_sz = sizeof (ilb_persist_info_t);
164*10946SSangeeta.Misra@Sun.COM 	if ((buf.buf = malloc((num_entries > 0 ? num_entries : NUM_ENTRIES) *
165*10946SSangeeta.Misra@Sun.COM 	    entry_sz)) == NULL) {
166*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_ENOMEM;
167*10946SSangeeta.Misra@Sun.COM 		goto out;
168*10946SSangeeta.Misra@Sun.COM 	}
169*10946SSangeeta.Misra@Sun.COM 
170*10946SSangeeta.Misra@Sun.COM 	rclib = ilb_open(&h);
171*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK)
172*10946SSangeeta.Misra@Sun.COM 		goto out;
173*10946SSangeeta.Misra@Sun.COM 
174*10946SSangeeta.Misra@Sun.COM 	do {
175*10946SSangeeta.Misra@Sun.COM 		num = num_entries > 0 ? num_entries : NUM_ENTRIES;
176*10946SSangeeta.Misra@Sun.COM 		bzero(buf.buf, num * entry_sz);
177*10946SSangeeta.Misra@Sun.COM 
178*10946SSangeeta.Misra@Sun.COM 		if (tbl == show_nat)
179*10946SSangeeta.Misra@Sun.COM 			rclib = ilb_show_nat(h, buf.nbuf, &num, &end);
180*10946SSangeeta.Misra@Sun.COM 		else
181*10946SSangeeta.Misra@Sun.COM 			rclib = ilb_show_persist(h, buf.pbuf, &num, &end);
182*10946SSangeeta.Misra@Sun.COM 
183*10946SSangeeta.Misra@Sun.COM 		if (rclib != ILB_STATUS_OK)
184*10946SSangeeta.Misra@Sun.COM 			break;
185*10946SSangeeta.Misra@Sun.COM 
186*10946SSangeeta.Misra@Sun.COM 		for (i = 0; i < num; i++) {
187*10946SSangeeta.Misra@Sun.COM 			if (tbl == show_nat)
188*10946SSangeeta.Misra@Sun.COM 				print_nat_info(&buf.nbuf[i]);
189*10946SSangeeta.Misra@Sun.COM 			else
190*10946SSangeeta.Misra@Sun.COM 				print_persist_info(&buf.pbuf[i]);
191*10946SSangeeta.Misra@Sun.COM 		}
192*10946SSangeeta.Misra@Sun.COM 		if (num_entries > 0) {
193*10946SSangeeta.Misra@Sun.COM 			num_entries -= num;
194*10946SSangeeta.Misra@Sun.COM 			if (num_entries <= 0)
195*10946SSangeeta.Misra@Sun.COM 				break;
196*10946SSangeeta.Misra@Sun.COM 		}
197*10946SSangeeta.Misra@Sun.COM 	} while (!end);
198*10946SSangeeta.Misra@Sun.COM 	free(buf.buf);
199*10946SSangeeta.Misra@Sun.COM out:
200*10946SSangeeta.Misra@Sun.COM 	if (h != ILB_INVALID_HANDLE)
201*10946SSangeeta.Misra@Sun.COM 		(void) ilb_close(h);
202*10946SSangeeta.Misra@Sun.COM 	if (rclib != ILB_STATUS_OK) {
203*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilb_errstr(rclib));
204*10946SSangeeta.Misra@Sun.COM 		rc = ILBADM_LIBERR;
205*10946SSangeeta.Misra@Sun.COM 	}
206*10946SSangeeta.Misra@Sun.COM 	if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
207*10946SSangeeta.Misra@Sun.COM 		ilbadm_err(ilbadm_errstr(rc));
208*10946SSangeeta.Misra@Sun.COM 	return (rc);
209*10946SSangeeta.Misra@Sun.COM }
210*10946SSangeeta.Misra@Sun.COM 
211*10946SSangeeta.Misra@Sun.COM 
212*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_show_nat(int argc,char * argv[])213*10946SSangeeta.Misra@Sun.COM ilbadm_show_nat(int argc, char *argv[])
214*10946SSangeeta.Misra@Sun.COM {
215*10946SSangeeta.Misra@Sun.COM 	return (ilbadm_show_info(argc, argv, show_nat));
216*10946SSangeeta.Misra@Sun.COM }
217*10946SSangeeta.Misra@Sun.COM 
218*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_show_persist(int argc,char * argv[])219*10946SSangeeta.Misra@Sun.COM ilbadm_show_persist(int argc, char *argv[])
220*10946SSangeeta.Misra@Sun.COM {
221*10946SSangeeta.Misra@Sun.COM 	return (ilbadm_show_info(argc, argv, show_persist));
222*10946SSangeeta.Misra@Sun.COM }
223