xref: /titanic_53/usr/src/cmd/cmd-inet/usr.sbin/ilbadm/ilbadm_nat.c (revision dbed73cbda2229fd1aa6dc5743993cae7f0a7ee9)
1*dbed73cbSSangeeta Misra /*
2*dbed73cbSSangeeta Misra  * CDDL HEADER START
3*dbed73cbSSangeeta Misra  *
4*dbed73cbSSangeeta Misra  * The contents of this file are subject to the terms of the
5*dbed73cbSSangeeta Misra  * Common Development and Distribution License (the "License").
6*dbed73cbSSangeeta Misra  * You may not use this file except in compliance with the License.
7*dbed73cbSSangeeta Misra  *
8*dbed73cbSSangeeta Misra  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*dbed73cbSSangeeta Misra  * or http://www.opensolaris.org/os/licensing.
10*dbed73cbSSangeeta Misra  * See the License for the specific language governing permissions
11*dbed73cbSSangeeta Misra  * and limitations under the License.
12*dbed73cbSSangeeta Misra  *
13*dbed73cbSSangeeta Misra  * When distributing Covered Code, include this CDDL HEADER in each
14*dbed73cbSSangeeta Misra  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*dbed73cbSSangeeta Misra  * If applicable, add the following below this CDDL HEADER, with the
16*dbed73cbSSangeeta Misra  * fields enclosed by brackets "[]" replaced with your own identifying
17*dbed73cbSSangeeta Misra  * information: Portions Copyright [yyyy] [name of copyright owner]
18*dbed73cbSSangeeta Misra  *
19*dbed73cbSSangeeta Misra  * CDDL HEADER END
20*dbed73cbSSangeeta Misra  */
21*dbed73cbSSangeeta Misra 
22*dbed73cbSSangeeta Misra /*
23*dbed73cbSSangeeta Misra  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*dbed73cbSSangeeta Misra  * Use is subject to license terms.
25*dbed73cbSSangeeta Misra  */
26*dbed73cbSSangeeta Misra 
27*dbed73cbSSangeeta Misra #include <sys/types.h>
28*dbed73cbSSangeeta Misra #include <sys/socket.h>
29*dbed73cbSSangeeta Misra #include <stdlib.h>
30*dbed73cbSSangeeta Misra #include <stdio.h>
31*dbed73cbSSangeeta Misra #include <strings.h>
32*dbed73cbSSangeeta Misra #include <netinet/in.h>
33*dbed73cbSSangeeta Misra #include <arpa/inet.h>
34*dbed73cbSSangeeta Misra #include <libilb.h>
35*dbed73cbSSangeeta Misra #include "ilbadm.h"
36*dbed73cbSSangeeta Misra 
37*dbed73cbSSangeeta Misra /*
38*dbed73cbSSangeeta Misra  * For each iteration through the kernel table, ask for at most NUM_ENTRIES
39*dbed73cbSSangeeta Misra  * entries to be returned.
40*dbed73cbSSangeeta Misra  */
41*dbed73cbSSangeeta Misra #define	NUM_ENTRIES	500
42*dbed73cbSSangeeta Misra 
43*dbed73cbSSangeeta Misra static void
print_nat_info(ilb_nat_info_t * info)44*dbed73cbSSangeeta Misra print_nat_info(ilb_nat_info_t *info)
45*dbed73cbSSangeeta Misra {
46*dbed73cbSSangeeta Misra 	char *tmp;
47*dbed73cbSSangeeta Misra 	ipaddr_t addr_v4;
48*dbed73cbSSangeeta Misra 	char addr[INET6_ADDRSTRLEN];
49*dbed73cbSSangeeta Misra 
50*dbed73cbSSangeeta Misra 	if (info->nat_proto == IPPROTO_TCP)
51*dbed73cbSSangeeta Misra 		tmp = "TCP";
52*dbed73cbSSangeeta Misra 	else if (info->nat_proto == IPPROTO_UDP)
53*dbed73cbSSangeeta Misra 		tmp = "UDP";
54*dbed73cbSSangeeta Misra 	else
55*dbed73cbSSangeeta Misra 		tmp = "Unknown";
56*dbed73cbSSangeeta Misra 	(void) printf("%4s: ", tmp);
57*dbed73cbSSangeeta Misra 
58*dbed73cbSSangeeta Misra 	if (IN6_IS_ADDR_V4MAPPED(&info->nat_out_global)) {
59*dbed73cbSSangeeta Misra 		IN6_V4MAPPED_TO_IPADDR(&info->nat_out_global, addr_v4);
60*dbed73cbSSangeeta Misra 		(void) printf("%s.%d > ", inet_ntop(AF_INET, &addr_v4, addr,
61*dbed73cbSSangeeta Misra 		    INET6_ADDRSTRLEN), ntohs(info->nat_out_global_port));
62*dbed73cbSSangeeta Misra 		IN6_V4MAPPED_TO_IPADDR(&info->nat_in_global, addr_v4);
63*dbed73cbSSangeeta Misra 		(void) printf("%s.%d >>> ", inet_ntop(AF_INET, &addr_v4, addr,
64*dbed73cbSSangeeta Misra 		    INET6_ADDRSTRLEN), ntohs(info->nat_in_global_port));
65*dbed73cbSSangeeta Misra 
66*dbed73cbSSangeeta Misra 		IN6_V4MAPPED_TO_IPADDR(&info->nat_out_local, addr_v4);
67*dbed73cbSSangeeta Misra 		(void) printf("%s.%d > ", inet_ntop(AF_INET, &addr_v4, addr,
68*dbed73cbSSangeeta Misra 		    INET6_ADDRSTRLEN), ntohs(info->nat_out_local_port));
69*dbed73cbSSangeeta Misra 		IN6_V4MAPPED_TO_IPADDR(&info->nat_in_local, addr_v4);
70*dbed73cbSSangeeta Misra 		(void) printf("%s.%d\n", inet_ntop(AF_INET, &addr_v4, addr,
71*dbed73cbSSangeeta Misra 		    INET6_ADDRSTRLEN), ntohs(info->nat_in_local_port));
72*dbed73cbSSangeeta Misra 	} else {
73*dbed73cbSSangeeta Misra 		(void) printf("%s.%d > ", inet_ntop(AF_INET6,
74*dbed73cbSSangeeta Misra 		    &info->nat_out_global, addr, INET6_ADDRSTRLEN),
75*dbed73cbSSangeeta Misra 		    ntohs(info->nat_out_global_port));
76*dbed73cbSSangeeta Misra 		(void) printf("%s.%d >>> ", inet_ntop(AF_INET6,
77*dbed73cbSSangeeta Misra 		    &info->nat_in_global, addr, INET6_ADDRSTRLEN),
78*dbed73cbSSangeeta Misra 		    ntohs(info->nat_in_global_port));
79*dbed73cbSSangeeta Misra 
80*dbed73cbSSangeeta Misra 		(void) printf("%s.%d > ", inet_ntop(AF_INET6,
81*dbed73cbSSangeeta Misra 		    &info->nat_out_local, addr, INET6_ADDRSTRLEN),
82*dbed73cbSSangeeta Misra 		    ntohs(info->nat_out_local_port));
83*dbed73cbSSangeeta Misra 		(void) printf("%s.%d\n", inet_ntop(AF_INET6,
84*dbed73cbSSangeeta Misra 		    &info->nat_in_local, addr, INET6_ADDRSTRLEN),
85*dbed73cbSSangeeta Misra 		    ntohs(info->nat_in_local_port));
86*dbed73cbSSangeeta Misra 	}
87*dbed73cbSSangeeta Misra }
88*dbed73cbSSangeeta Misra 
89*dbed73cbSSangeeta Misra static void
print_persist_info(ilb_persist_info_t * info)90*dbed73cbSSangeeta Misra print_persist_info(ilb_persist_info_t *info)
91*dbed73cbSSangeeta Misra {
92*dbed73cbSSangeeta Misra 	char addr[INET6_ADDRSTRLEN];
93*dbed73cbSSangeeta Misra 
94*dbed73cbSSangeeta Misra 	(void) printf("%s: ", info->persist_rule_name);
95*dbed73cbSSangeeta Misra 	if (IN6_IS_ADDR_V4MAPPED(&info->persist_req_addr)) {
96*dbed73cbSSangeeta Misra 		ipaddr_t addr_v4;
97*dbed73cbSSangeeta Misra 
98*dbed73cbSSangeeta Misra 		IN6_V4MAPPED_TO_IPADDR(&info->persist_req_addr, addr_v4);
99*dbed73cbSSangeeta Misra 		(void) printf("%s --> ", inet_ntop(AF_INET, &addr_v4, addr,
100*dbed73cbSSangeeta Misra 		    INET6_ADDRSTRLEN));
101*dbed73cbSSangeeta Misra 		IN6_V4MAPPED_TO_IPADDR(&info->persist_srv_addr, addr_v4);
102*dbed73cbSSangeeta Misra 		(void) printf("%s\n", inet_ntop(AF_INET, &addr_v4, addr,
103*dbed73cbSSangeeta Misra 		    INET6_ADDRSTRLEN));
104*dbed73cbSSangeeta Misra 	} else {
105*dbed73cbSSangeeta Misra 		(void) printf("%s --> ", inet_ntop(AF_INET6,
106*dbed73cbSSangeeta Misra 		    &info->persist_req_addr, addr, INET6_ADDRSTRLEN));
107*dbed73cbSSangeeta Misra 		(void) printf("%s\n", inet_ntop(AF_INET6,
108*dbed73cbSSangeeta Misra 		    &info->persist_srv_addr, addr, INET6_ADDRSTRLEN));
109*dbed73cbSSangeeta Misra 	}
110*dbed73cbSSangeeta Misra }
111*dbed73cbSSangeeta Misra 
112*dbed73cbSSangeeta Misra /* Tell ilbadm_show_info() which table to show. */
113*dbed73cbSSangeeta Misra enum which_tbl {
114*dbed73cbSSangeeta Misra 	show_nat = 1,
115*dbed73cbSSangeeta Misra 	show_persist
116*dbed73cbSSangeeta Misra };
117*dbed73cbSSangeeta Misra 
118*dbed73cbSSangeeta Misra typedef union {
119*dbed73cbSSangeeta Misra 	ilb_nat_info_t		*nbuf;
120*dbed73cbSSangeeta Misra 	ilb_persist_info_t	*pbuf;
121*dbed73cbSSangeeta Misra 	char			*buf;
122*dbed73cbSSangeeta Misra } show_buf_t;
123*dbed73cbSSangeeta Misra 
124*dbed73cbSSangeeta Misra static ilbadm_status_t
ilbadm_show_info(int argc,char * argv[],enum which_tbl tbl)125*dbed73cbSSangeeta Misra ilbadm_show_info(int argc, char *argv[], enum which_tbl tbl)
126*dbed73cbSSangeeta Misra {
127*dbed73cbSSangeeta Misra 	ilb_handle_t		h = ILB_INVALID_HANDLE;
128*dbed73cbSSangeeta Misra 	show_buf_t		buf;
129*dbed73cbSSangeeta Misra 	ilb_status_t		rclib = ILB_STATUS_OK;
130*dbed73cbSSangeeta Misra 	ilbadm_status_t		rc = ILBADM_OK;
131*dbed73cbSSangeeta Misra 	int32_t			i, num_entries;
132*dbed73cbSSangeeta Misra 	size_t			num;
133*dbed73cbSSangeeta Misra 	boolean_t		end;
134*dbed73cbSSangeeta Misra 	size_t			entry_sz;
135*dbed73cbSSangeeta Misra 
136*dbed73cbSSangeeta Misra 	/*
137*dbed73cbSSangeeta Misra 	 * If the user does not specify a count, return the whole table.
138*dbed73cbSSangeeta Misra 	 * This requires setting the fourth param to ilb_show_nat/persist()
139*dbed73cbSSangeeta Misra 	 * end to B_FALSE.  Otherwise, set end to B_TRUE;
140*dbed73cbSSangeeta Misra 	 */
141*dbed73cbSSangeeta Misra 
142*dbed73cbSSangeeta Misra 	switch (argc) {
143*dbed73cbSSangeeta Misra 	case 1:
144*dbed73cbSSangeeta Misra 		num_entries = -1;
145*dbed73cbSSangeeta Misra 		end = B_FALSE;
146*dbed73cbSSangeeta Misra 		break;
147*dbed73cbSSangeeta Misra 	case 2:
148*dbed73cbSSangeeta Misra 		num_entries = atoi(argv[1]);
149*dbed73cbSSangeeta Misra 		if (num_entries < 1) {
150*dbed73cbSSangeeta Misra 			rc = ILBADM_EINVAL;
151*dbed73cbSSangeeta Misra 			goto out;
152*dbed73cbSSangeeta Misra 		}
153*dbed73cbSSangeeta Misra 		end = B_TRUE;
154*dbed73cbSSangeeta Misra 		break;
155*dbed73cbSSangeeta Misra 	default:
156*dbed73cbSSangeeta Misra 		rc = ILBADM_EINVAL;
157*dbed73cbSSangeeta Misra 		goto out;
158*dbed73cbSSangeeta Misra 	}
159*dbed73cbSSangeeta Misra 
160*dbed73cbSSangeeta Misra 	if (tbl == show_nat)
161*dbed73cbSSangeeta Misra 		entry_sz = sizeof (ilb_nat_info_t);
162*dbed73cbSSangeeta Misra 	else
163*dbed73cbSSangeeta Misra 		entry_sz = sizeof (ilb_persist_info_t);
164*dbed73cbSSangeeta Misra 	if ((buf.buf = malloc((num_entries > 0 ? num_entries : NUM_ENTRIES) *
165*dbed73cbSSangeeta Misra 	    entry_sz)) == NULL) {
166*dbed73cbSSangeeta Misra 		rc = ILBADM_ENOMEM;
167*dbed73cbSSangeeta Misra 		goto out;
168*dbed73cbSSangeeta Misra 	}
169*dbed73cbSSangeeta Misra 
170*dbed73cbSSangeeta Misra 	rclib = ilb_open(&h);
171*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK)
172*dbed73cbSSangeeta Misra 		goto out;
173*dbed73cbSSangeeta Misra 
174*dbed73cbSSangeeta Misra 	do {
175*dbed73cbSSangeeta Misra 		num = num_entries > 0 ? num_entries : NUM_ENTRIES;
176*dbed73cbSSangeeta Misra 		bzero(buf.buf, num * entry_sz);
177*dbed73cbSSangeeta Misra 
178*dbed73cbSSangeeta Misra 		if (tbl == show_nat)
179*dbed73cbSSangeeta Misra 			rclib = ilb_show_nat(h, buf.nbuf, &num, &end);
180*dbed73cbSSangeeta Misra 		else
181*dbed73cbSSangeeta Misra 			rclib = ilb_show_persist(h, buf.pbuf, &num, &end);
182*dbed73cbSSangeeta Misra 
183*dbed73cbSSangeeta Misra 		if (rclib != ILB_STATUS_OK)
184*dbed73cbSSangeeta Misra 			break;
185*dbed73cbSSangeeta Misra 
186*dbed73cbSSangeeta Misra 		for (i = 0; i < num; i++) {
187*dbed73cbSSangeeta Misra 			if (tbl == show_nat)
188*dbed73cbSSangeeta Misra 				print_nat_info(&buf.nbuf[i]);
189*dbed73cbSSangeeta Misra 			else
190*dbed73cbSSangeeta Misra 				print_persist_info(&buf.pbuf[i]);
191*dbed73cbSSangeeta Misra 		}
192*dbed73cbSSangeeta Misra 		if (num_entries > 0) {
193*dbed73cbSSangeeta Misra 			num_entries -= num;
194*dbed73cbSSangeeta Misra 			if (num_entries <= 0)
195*dbed73cbSSangeeta Misra 				break;
196*dbed73cbSSangeeta Misra 		}
197*dbed73cbSSangeeta Misra 	} while (!end);
198*dbed73cbSSangeeta Misra 	free(buf.buf);
199*dbed73cbSSangeeta Misra out:
200*dbed73cbSSangeeta Misra 	if (h != ILB_INVALID_HANDLE)
201*dbed73cbSSangeeta Misra 		(void) ilb_close(h);
202*dbed73cbSSangeeta Misra 	if (rclib != ILB_STATUS_OK) {
203*dbed73cbSSangeeta Misra 		ilbadm_err(ilb_errstr(rclib));
204*dbed73cbSSangeeta Misra 		rc = ILBADM_LIBERR;
205*dbed73cbSSangeeta Misra 	}
206*dbed73cbSSangeeta Misra 	if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
207*dbed73cbSSangeeta Misra 		ilbadm_err(ilbadm_errstr(rc));
208*dbed73cbSSangeeta Misra 	return (rc);
209*dbed73cbSSangeeta Misra }
210*dbed73cbSSangeeta Misra 
211*dbed73cbSSangeeta Misra 
212*dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_show_nat(int argc,char * argv[])213*dbed73cbSSangeeta Misra ilbadm_show_nat(int argc, char *argv[])
214*dbed73cbSSangeeta Misra {
215*dbed73cbSSangeeta Misra 	return (ilbadm_show_info(argc, argv, show_nat));
216*dbed73cbSSangeeta Misra }
217*dbed73cbSSangeeta Misra 
218*dbed73cbSSangeeta Misra ilbadm_status_t
ilbadm_show_persist(int argc,char * argv[])219*dbed73cbSSangeeta Misra ilbadm_show_persist(int argc, char *argv[])
220*dbed73cbSSangeeta Misra {
221*dbed73cbSSangeeta Misra 	return (ilbadm_show_info(argc, argv, show_persist));
222*dbed73cbSSangeeta Misra }
223