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 <stdlib.h> 28*dbed73cbSSangeeta Misra #include <strings.h> 29*dbed73cbSSangeeta Misra #include <unistd.h> 30*dbed73cbSSangeeta Misra #include <stddef.h> 31*dbed73cbSSangeeta Misra #include <sys/types.h> 32*dbed73cbSSangeeta Misra #include <sys/socket.h> 33*dbed73cbSSangeeta Misra #include "libilb.h" 34*dbed73cbSSangeeta Misra #include "libilb_impl.h" 35*dbed73cbSSangeeta Misra 36*dbed73cbSSangeeta Misra enum which_tbl { 37*dbed73cbSSangeeta Misra show_nat = 1, 38*dbed73cbSSangeeta Misra show_persist 39*dbed73cbSSangeeta Misra }; 40*dbed73cbSSangeeta Misra 41*dbed73cbSSangeeta Misra /* The common function to show kernel info. */ 42*dbed73cbSSangeeta Misra static ilb_status_t ilb_show_info(ilb_handle_t, char *, size_t *, boolean_t *, 43*dbed73cbSSangeeta Misra enum which_tbl); 44*dbed73cbSSangeeta Misra 45*dbed73cbSSangeeta Misra /* 46*dbed73cbSSangeeta Misra * To get the ILB NAT table. 47*dbed73cbSSangeeta Misra * 48*dbed73cbSSangeeta Misra * buf: The buffer to return the NAT table entries. 49*dbed73cbSSangeeta Misra * num: The caller sets it to the number of ilb_nat_info_t entries buf can 50*dbed73cbSSangeeta Misra * hold. On return, it contains the actual number of entries put in buf. 51*dbed73cbSSangeeta Misra * end: The caller sets it to B_TRUE if it only wants at most num entries to 52*dbed73cbSSangeeta Misra * be returned. The transaction to ilbd will be termianted when this 53*dbed73cbSSangeeta Misra * call returns. 54*dbed73cbSSangeeta Misra * The caller sets it to B_FALSE if it intends to get the whole table. 55*dbed73cbSSangeeta Misra * If the whole table has more than num entries, the caller can call 56*dbed73cbSSangeeta Misra * this function again to retrieve the rest of the table. 57*dbed73cbSSangeeta Misra * On return, end is set to B_TRUE if end of table is reached; B_FALSE 58*dbed73cbSSangeeta Misra * if there are still remaining entries. 59*dbed73cbSSangeeta Misra */ 60*dbed73cbSSangeeta Misra ilb_status_t 61*dbed73cbSSangeeta Misra ilb_show_nat(ilb_handle_t h, ilb_nat_info_t buf[], size_t *num, 62*dbed73cbSSangeeta Misra boolean_t *end) 63*dbed73cbSSangeeta Misra { 64*dbed73cbSSangeeta Misra return (ilb_show_info(h, (char *)buf, num, end, show_nat)); 65*dbed73cbSSangeeta Misra } 66*dbed73cbSSangeeta Misra 67*dbed73cbSSangeeta Misra /* 68*dbed73cbSSangeeta Misra * To get the ILB persistent entry table. 69*dbed73cbSSangeeta Misra * 70*dbed73cbSSangeeta Misra * buf: The buffer to return the persistent table entries. 71*dbed73cbSSangeeta Misra * num: The caller sets it to the number of ilb_persist_info_t entries buf can 72*dbed73cbSSangeeta Misra * hold. On return, it contains the actual number of entries put in buf. 73*dbed73cbSSangeeta Misra * end: The caller sets it to B_TRUE if it only wants at most num entries to 74*dbed73cbSSangeeta Misra * be returned. The transaction to ilbd will be termianted when this 75*dbed73cbSSangeeta Misra * call returns. 76*dbed73cbSSangeeta Misra * The caller sets it to B_FALSE if it intends to get the whole table. 77*dbed73cbSSangeeta Misra * If the whole table has more than num entries, the caller can call 78*dbed73cbSSangeeta Misra * this function again to retrieve the rest of the table. 79*dbed73cbSSangeeta Misra * On return, end is set to B_TRUE if end of table is reached; B_FALSE 80*dbed73cbSSangeeta Misra * if there are still remaining entries. 81*dbed73cbSSangeeta Misra */ 82*dbed73cbSSangeeta Misra ilb_status_t 83*dbed73cbSSangeeta Misra ilb_show_persist(ilb_handle_t h, ilb_persist_info_t buf[], size_t *num, 84*dbed73cbSSangeeta Misra boolean_t *end) 85*dbed73cbSSangeeta Misra { 86*dbed73cbSSangeeta Misra return (ilb_show_info(h, (char *)buf, num, end, show_persist)); 87*dbed73cbSSangeeta Misra } 88*dbed73cbSSangeeta Misra 89*dbed73cbSSangeeta Misra /* 90*dbed73cbSSangeeta Misra * The function doing the work... The tbl parameter determines whith table 91*dbed73cbSSangeeta Misra * to show. 92*dbed73cbSSangeeta Misra */ 93*dbed73cbSSangeeta Misra static ilb_status_t 94*dbed73cbSSangeeta Misra ilb_show_info(ilb_handle_t h, char *buf, size_t *num, boolean_t *end, 95*dbed73cbSSangeeta Misra enum which_tbl tbl) 96*dbed73cbSSangeeta Misra { 97*dbed73cbSSangeeta Misra ilb_comm_t *req, *rbuf; 98*dbed73cbSSangeeta Misra ilb_show_info_t *req_si, *tmp_si; 99*dbed73cbSSangeeta Misra size_t reqsz, rbufsz, tmp_rbufsz, cur_num; 100*dbed73cbSSangeeta Misra size_t entry_sz; 101*dbed73cbSSangeeta Misra ilb_status_t rc; 102*dbed73cbSSangeeta Misra 103*dbed73cbSSangeeta Misra if (*num == 0) 104*dbed73cbSSangeeta Misra return (ILB_STATUS_EINVAL); 105*dbed73cbSSangeeta Misra 106*dbed73cbSSangeeta Misra reqsz = sizeof (ilb_comm_t) + sizeof (ilb_show_info_t); 107*dbed73cbSSangeeta Misra if ((req = malloc(reqsz)) == NULL) 108*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 109*dbed73cbSSangeeta Misra req_si = (ilb_show_info_t *)&req->ic_data; 110*dbed73cbSSangeeta Misra 111*dbed73cbSSangeeta Misra /* 112*dbed73cbSSangeeta Misra * Need to allocate a receive buffer and then copy the buffer 113*dbed73cbSSangeeta Misra * content to the passed in buf. The reason is that the 114*dbed73cbSSangeeta Misra * communication to ilbd is message based and the protocol 115*dbed73cbSSangeeta Misra * includes a header in the reply. We need to remove this header 116*dbed73cbSSangeeta Misra * from the message, hence the copying... 117*dbed73cbSSangeeta Misra */ 118*dbed73cbSSangeeta Misra if (tbl == show_nat) 119*dbed73cbSSangeeta Misra entry_sz = sizeof (ilb_nat_info_t); 120*dbed73cbSSangeeta Misra else 121*dbed73cbSSangeeta Misra entry_sz = sizeof (ilb_persist_info_t); 122*dbed73cbSSangeeta Misra rbufsz = *num * entry_sz + sizeof (ilb_comm_t) + 123*dbed73cbSSangeeta Misra sizeof (ilb_show_info_t); 124*dbed73cbSSangeeta Misra if ((rbuf = malloc(rbufsz)) == NULL) { 125*dbed73cbSSangeeta Misra free(req); 126*dbed73cbSSangeeta Misra return (ILB_STATUS_ENOMEM); 127*dbed73cbSSangeeta Misra } 128*dbed73cbSSangeeta Misra 129*dbed73cbSSangeeta Misra if (tbl == show_nat) 130*dbed73cbSSangeeta Misra req->ic_cmd = ILBD_SHOW_NAT; 131*dbed73cbSSangeeta Misra else 132*dbed73cbSSangeeta Misra req->ic_cmd = ILBD_SHOW_PERSIST; 133*dbed73cbSSangeeta Misra req->ic_flags = 0; 134*dbed73cbSSangeeta Misra req_si->sn_num = *num; 135*dbed73cbSSangeeta Misra cur_num = 0; 136*dbed73cbSSangeeta Misra 137*dbed73cbSSangeeta Misra do { 138*dbed73cbSSangeeta Misra tmp_rbufsz = rbufsz; 139*dbed73cbSSangeeta Misra rc = i_ilb_do_comm(h, req, reqsz, rbuf, &tmp_rbufsz); 140*dbed73cbSSangeeta Misra if (rc != ILB_STATUS_OK) 141*dbed73cbSSangeeta Misra goto out; 142*dbed73cbSSangeeta Misra if (rbuf->ic_cmd != ILBD_CMD_OK) { 143*dbed73cbSSangeeta Misra rc = *(ilb_status_t *)&rbuf->ic_data; 144*dbed73cbSSangeeta Misra goto out; 145*dbed73cbSSangeeta Misra } 146*dbed73cbSSangeeta Misra 147*dbed73cbSSangeeta Misra tmp_si = (ilb_show_info_t *)&rbuf->ic_data; 148*dbed73cbSSangeeta Misra 149*dbed73cbSSangeeta Misra cur_num += tmp_si->sn_num; 150*dbed73cbSSangeeta Misra bcopy(&tmp_si->sn_data, buf, tmp_si->sn_num * entry_sz); 151*dbed73cbSSangeeta Misra buf += tmp_si->sn_num * entry_sz; 152*dbed73cbSSangeeta Misra 153*dbed73cbSSangeeta Misra /* 154*dbed73cbSSangeeta Misra * Buffer is filled, regardless of this is the end of table or 155*dbed73cbSSangeeta Misra * not, we need to stop. 156*dbed73cbSSangeeta Misra */ 157*dbed73cbSSangeeta Misra if (cur_num == *num) 158*dbed73cbSSangeeta Misra break; 159*dbed73cbSSangeeta Misra /* Try to fill in the rest. */ 160*dbed73cbSSangeeta Misra req_si->sn_num = *num - cur_num; 161*dbed73cbSSangeeta Misra } while (!(rbuf->ic_flags & ILB_COMM_END)); 162*dbed73cbSSangeeta Misra 163*dbed73cbSSangeeta Misra *num = cur_num; 164*dbed73cbSSangeeta Misra 165*dbed73cbSSangeeta Misra /* End of transaction, let the caller know. */ 166*dbed73cbSSangeeta Misra if (rbuf->ic_flags & ILB_COMM_END) { 167*dbed73cbSSangeeta Misra *end = B_TRUE; 168*dbed73cbSSangeeta Misra } else { 169*dbed73cbSSangeeta Misra /* The user wants to terminate the transaction */ 170*dbed73cbSSangeeta Misra if (*end) { 171*dbed73cbSSangeeta Misra req->ic_flags = ILB_COMM_END; 172*dbed73cbSSangeeta Misra tmp_rbufsz = rbufsz; 173*dbed73cbSSangeeta Misra rc = i_ilb_do_comm(h, req, reqsz, rbuf, &tmp_rbufsz); 174*dbed73cbSSangeeta Misra } 175*dbed73cbSSangeeta Misra } 176*dbed73cbSSangeeta Misra out: 177*dbed73cbSSangeeta Misra free(req); 178*dbed73cbSSangeeta Misra free(rbuf); 179*dbed73cbSSangeeta Misra return (rc); 180*dbed73cbSSangeeta Misra } 181