ilb_nat.c revision 10946:324bab2b3370
199461Sobrien/* 2218822Sdim * CDDL HEADER START 3218822Sdim * 499461Sobrien * The contents of this file are subject to the terms of the 599461Sobrien * Common Development and Distribution License (the "License"). 699461Sobrien * You may not use this file except in compliance with the License. 799461Sobrien * 899461Sobrien * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 999461Sobrien * or http://www.opensolaris.org/os/licensing. 1099461Sobrien * See the License for the specific language governing permissions 1199461Sobrien * and limitations under the License. 1299461Sobrien * 1399461Sobrien * When distributing Covered Code, include this CDDL HEADER in each 1499461Sobrien * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1599461Sobrien * If applicable, add the following below this CDDL HEADER, with the 1699461Sobrien * fields enclosed by brackets "[]" replaced with your own identifying 1799461Sobrien * information: Portions Copyright [yyyy] [name of copyright owner] 1899461Sobrien * 1999461Sobrien * CDDL HEADER END 20218822Sdim */ 21218822Sdim 2299461Sobrien/* 2399461Sobrien * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2499461Sobrien * Use is subject to license terms. 2599461Sobrien */ 2699461Sobrien 27130561Sobrien#include <stdlib.h> 28130561Sobrien#include <strings.h> 2999461Sobrien#include <unistd.h> 3099461Sobrien#include <stddef.h> 3199461Sobrien#include <sys/types.h> 3299461Sobrien#include <sys/socket.h> 3399461Sobrien#include "libilb.h" 3499461Sobrien#include "libilb_impl.h" 3599461Sobrien 3699461Sobrienenum which_tbl { 3799461Sobrien show_nat = 1, 3899461Sobrien show_persist 39130561Sobrien}; 4099461Sobrien 41130561Sobrien/* The common function to show kernel info. */ 42130561Sobrienstatic ilb_status_t ilb_show_info(ilb_handle_t, char *, size_t *, boolean_t *, 43130561Sobrien enum which_tbl); 44130561Sobrien 4599461Sobrien/* 46130561Sobrien * To get the ILB NAT table. 4799461Sobrien * 4899461Sobrien * buf: The buffer to return the NAT table entries. 49130561Sobrien * num: The caller sets it to the number of ilb_nat_info_t entries buf can 5099461Sobrien * hold. On return, it contains the actual number of entries put in buf. 5199461Sobrien * end: The caller sets it to B_TRUE if it only wants at most num entries to 52130561Sobrien * be returned. The transaction to ilbd will be termianted when this 5399461Sobrien * call returns. 5499461Sobrien * The caller sets it to B_FALSE if it intends to get the whole table. 5599461Sobrien * If the whole table has more than num entries, the caller can call 5699461Sobrien * this function again to retrieve the rest of the table. 5799461Sobrien * On return, end is set to B_TRUE if end of table is reached; B_FALSE 5899461Sobrien * if there are still remaining entries. 5999461Sobrien */ 6099461Sobrienilb_status_t 6199461Sobrienilb_show_nat(ilb_handle_t h, ilb_nat_info_t buf[], size_t *num, 6299461Sobrien boolean_t *end) 6399461Sobrien{ 6499461Sobrien return (ilb_show_info(h, (char *)buf, num, end, show_nat)); 6599461Sobrien} 6699461Sobrien 6799461Sobrien/* 6899461Sobrien * To get the ILB persistent entry table. 6999461Sobrien * 7099461Sobrien * buf: The buffer to return the persistent table entries. 7199461Sobrien * num: The caller sets it to the number of ilb_persist_info_t entries buf can 7299461Sobrien * hold. On return, it contains the actual number of entries put in buf. 7399461Sobrien * end: The caller sets it to B_TRUE if it only wants at most num entries to 74130561Sobrien * be returned. The transaction to ilbd will be termianted when this 75130561Sobrien * call returns. 76130561Sobrien * The caller sets it to B_FALSE if it intends to get the whole table. 7799461Sobrien * If the whole table has more than num entries, the caller can call 7899461Sobrien * this function again to retrieve the rest of the table. 7999461Sobrien * On return, end is set to B_TRUE if end of table is reached; B_FALSE 8099461Sobrien * if there are still remaining entries. 8199461Sobrien */ 8299461Sobrienilb_status_t 8399461Sobrienilb_show_persist(ilb_handle_t h, ilb_persist_info_t buf[], size_t *num, 8499461Sobrien boolean_t *end) 8599461Sobrien{ 8699461Sobrien return (ilb_show_info(h, (char *)buf, num, end, show_persist)); 8799461Sobrien} 8899461Sobrien 89107492Sobrien/* 9099461Sobrien * The function doing the work... The tbl parameter determines whith table 9199461Sobrien * to show. 9299461Sobrien */ 9399461Sobrienstatic ilb_status_t 9499461Sobrienilb_show_info(ilb_handle_t h, char *buf, size_t *num, boolean_t *end, 9599461Sobrien enum which_tbl tbl) 9699461Sobrien{ 9799461Sobrien ilb_comm_t *req, *rbuf; 9899461Sobrien ilb_show_info_t *req_si, *tmp_si; 9999461Sobrien size_t reqsz, rbufsz, tmp_rbufsz, cur_num; 10099461Sobrien size_t entry_sz; 10199461Sobrien ilb_status_t rc; 10299461Sobrien 10399461Sobrien if (*num == 0) 10499461Sobrien return (ILB_STATUS_EINVAL); 10599461Sobrien 10699461Sobrien reqsz = sizeof (ilb_comm_t) + sizeof (ilb_show_info_t); 10799461Sobrien if ((req = malloc(reqsz)) == NULL) 10899461Sobrien return (ILB_STATUS_ENOMEM); 10999461Sobrien req_si = (ilb_show_info_t *)&req->ic_data; 11099461Sobrien 11199461Sobrien /* 11299461Sobrien * Need to allocate a receive buffer and then copy the buffer 11399461Sobrien * content to the passed in buf. The reason is that the 11499461Sobrien * communication to ilbd is message based and the protocol 11599461Sobrien * includes a header in the reply. We need to remove this header 11699461Sobrien * from the message, hence the copying... 11799461Sobrien */ 11899461Sobrien if (tbl == show_nat) 11999461Sobrien entry_sz = sizeof (ilb_nat_info_t); 12099461Sobrien else 12199461Sobrien entry_sz = sizeof (ilb_persist_info_t); 12299461Sobrien rbufsz = *num * entry_sz + sizeof (ilb_comm_t) + 12399461Sobrien sizeof (ilb_show_info_t); 12499461Sobrien if ((rbuf = malloc(rbufsz)) == NULL) { 12599461Sobrien free(req); 12699461Sobrien return (ILB_STATUS_ENOMEM); 12799461Sobrien } 128107492Sobrien 12999461Sobrien if (tbl == show_nat) 13099461Sobrien req->ic_cmd = ILBD_SHOW_NAT; 13199461Sobrien else 13299461Sobrien req->ic_cmd = ILBD_SHOW_PERSIST; 13399461Sobrien req->ic_flags = 0; 13499461Sobrien req_si->sn_num = *num; 13599461Sobrien cur_num = 0; 13699461Sobrien 13799461Sobrien do { 13899461Sobrien tmp_rbufsz = rbufsz; 13999461Sobrien rc = i_ilb_do_comm(h, req, reqsz, rbuf, &tmp_rbufsz); 14099461Sobrien if (rc != ILB_STATUS_OK) 14199461Sobrien goto out; 14299461Sobrien if (rbuf->ic_cmd != ILBD_CMD_OK) { 14399461Sobrien rc = *(ilb_status_t *)&rbuf->ic_data; 14499461Sobrien goto out; 14599461Sobrien } 14699461Sobrien 14799461Sobrien tmp_si = (ilb_show_info_t *)&rbuf->ic_data; 14899461Sobrien 14999461Sobrien cur_num += tmp_si->sn_num; 15099461Sobrien bcopy(&tmp_si->sn_data, buf, tmp_si->sn_num * entry_sz); 15199461Sobrien buf += tmp_si->sn_num * entry_sz; 15299461Sobrien 15399461Sobrien /* 15499461Sobrien * Buffer is filled, regardless of this is the end of table or 15599461Sobrien * not, we need to stop. 15699461Sobrien */ 15799461Sobrien if (cur_num == *num) 15899461Sobrien break; 15999461Sobrien /* Try to fill in the rest. */ 16099461Sobrien req_si->sn_num = *num - cur_num; 16199461Sobrien } while (!(rbuf->ic_flags & ILB_COMM_END)); 16299461Sobrien 16399461Sobrien *num = cur_num; 16499461Sobrien 16599461Sobrien /* End of transaction, let the caller know. */ 16699461Sobrien if (rbuf->ic_flags & ILB_COMM_END) { 16799461Sobrien *end = B_TRUE; 16899461Sobrien } else { 16999461Sobrien /* The user wants to terminate the transaction */ 17099461Sobrien if (*end) { 17199461Sobrien req->ic_flags = ILB_COMM_END; 17299461Sobrien tmp_rbufsz = rbufsz; 17399461Sobrien rc = i_ilb_do_comm(h, req, reqsz, rbuf, &tmp_rbufsz); 17499461Sobrien } 17599461Sobrien } 17699461Sobrienout: 17799461Sobrien free(req); 17899461Sobrien free(rbuf); 17999461Sobrien return (rc); 18099461Sobrien} 18199461Sobrien