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