summaryrefslogtreecommitdiffstats
path: root/lib/libatm/ioctl_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libatm/ioctl_subr.c')
-rw-r--r--lib/libatm/ioctl_subr.c515
1 files changed, 515 insertions, 0 deletions
diff --git a/lib/libatm/ioctl_subr.c b/lib/libatm/ioctl_subr.c
new file mode 100644
index 0000000..a77d79f
--- /dev/null
+++ b/lib/libatm/ioctl_subr.c
@@ -0,0 +1,515 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $Id: ioctl_subr.c,v 1.2 1998/07/10 17:09:20 root Exp $
+ *
+ */
+
+/*
+ * User Space Library Functions
+ * ----------------------------
+ *
+ * IOCTL subroutines
+ *
+ */
+
+#ifndef lint
+static char *RCSid = "@(#) $Id: ioctl_subr.c,v 1.2 1998/07/10 17:09:20 root Exp $";
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netatm/port.h>
+#include <netatm/atm.h>
+#include <netatm/atm_if.h>
+#include <netatm/atm_sap.h>
+#include <netatm/atm_sys.h>
+#include <netatm/atm_ioctl.h>
+
+#include "libatm.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+extern char *prog;
+
+
+/*
+ * Issue an informational IOCTL
+ *
+ * The user fills out the opcode and any subtype information. This
+ * routine will allocate a buffer and issue the IOCTL. If the request
+ * fails because the buffer wasn't big enough, this routine will double
+ * the buffer size and retry the request repeatedly. The buffer must
+ * be freed by the caller.
+ *
+ * Arguments:
+ * req pointer to an ATM information request IOCTL structure
+ * buf_len length of buffer to be allocated
+ *
+ * Returns:
+ * -1 error encountered (reason in errno)
+ * int length of the returned VCC information
+ *
+ */
+int
+do_info_ioctl(req, buf_len)
+ struct atminfreq *req;
+ int buf_len;
+{
+ int rc, s;
+ caddr_t buf;
+
+ /*
+ * Open a socket for the IOCTL
+ */
+ s = socket(AF_ATM, SOCK_DGRAM, 0);
+ if (s < 0) {
+ return(-1);
+ }
+
+ /*
+ * Get memory for returned information
+ */
+mem_retry:
+ buf = (caddr_t)UM_ALLOC(buf_len);
+ if (buf == NULL) {
+ errno = ENOMEM;
+ return(-1);
+ }
+
+ /*
+ * Set the buffer address and length in the request
+ */
+ req->air_buf_addr = buf;
+ req->air_buf_len = buf_len;
+
+ /*
+ * Issue the IOCTL
+ */
+ rc = ioctl(s, AIOCINFO, (caddr_t)req);
+ if (rc) {
+ UM_FREE(buf);
+ if (errno == ENOSPC) {
+ buf_len = buf_len * 2;
+ goto mem_retry;
+ }
+ return(-1);
+ }
+ (void)close(s);
+ /*
+ * Set a pointer to the returned info in the request
+ * and return its length
+ */
+ req->air_buf_addr = buf;
+ return(req->air_buf_len);
+}
+
+
+/*
+ * Get VCC information
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ * vccp pointer to a pointer to a struct air_vcc_rsp for the
+ * address of the returned VCC information
+ *
+ * Returns:
+ * int length of the retuned VCC information
+ *
+ */
+int
+get_vcc_info(intf, vccp)
+ char *intf;
+ struct air_vcc_rsp **vccp;
+{
+ int buf_len = sizeof(struct air_vcc_rsp) * 100;
+ struct atminfreq air;
+
+ /*
+ * Initialize IOCTL request
+ */
+ air.air_opcode = AIOCS_INF_VCC;
+ UM_ZERO(air.air_vcc_intf, sizeof(air.air_vcc_intf));
+ if (intf != NULL && strlen(intf) != 0)
+ strcpy(air.air_vcc_intf, intf);
+
+ buf_len = do_info_ioctl(&air, buf_len);
+
+ /*
+ * Return a pointer to the VCC info and its length
+ */
+ *vccp = (struct air_vcc_rsp *) air.air_buf_addr;
+ return(buf_len);
+}
+
+
+/*
+ * Count number of open VCCs
+ *
+ * Issue a AIOCS_INF_VCC to get info on all open VCCs. Count them and
+ * return the answer.
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ *
+ * Returns:
+ * int number of VCCs
+ *
+ */
+int
+count_vccs ( intf )
+char *intf;
+{
+ int vcc_info_len;
+ int count = 0;
+ char *cp;
+ struct air_vcc_rsp *vcc_info, *vcc_info_base;
+
+ vcc_info_len = get_vcc_info ( intf, &vcc_info );
+ if ( !vcc_info )
+ return ( 0 );
+ vcc_info_base = vcc_info;
+
+ for ( ; vcc_info_len >= sizeof ( struct air_vcc_rsp );
+ vcc_info_len -= sizeof ( struct air_vcc_rsp ),
+ vcc_info++ ) {
+ count++;
+ }
+ free ( vcc_info_base );
+ return ( count );
+}
+
+
+/*
+ * Get subnet mask
+ *
+ * Arguments:
+ * intf pointer to an interface name
+ * mask pointer to a struct sockaddr_in to receive the mask
+ *
+ * Returns:
+ * 0 good completion
+ * -1 error
+ *
+ */
+int
+get_subnet_mask(intf, mask)
+ char *intf;
+ struct sockaddr_in *mask;
+{
+ int rc, s;
+ struct ifreq req;
+ struct sockaddr_in *ip_mask;
+
+ /*
+ * Check parameters
+ */
+ if (!intf || !mask ||
+ strlen(intf) == 0 ||
+ strlen(intf) > IFNAMSIZ-1)
+ return(-1);
+
+ /*
+ * Open a socket for the IOCTL
+ */
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ return(-1);
+
+ /*
+ * Set up and issue the IOCTL
+ */
+ UM_ZERO(&req, sizeof(req));
+ strcpy(req.ifr_name, intf);
+ rc = ioctl(s, SIOCGIFNETMASK, (caddr_t)&req);
+ (void)close(s);
+ if (rc)
+ return(-1);
+
+ /*
+ * Give the answer back to the caller
+ */
+ ip_mask = (struct sockaddr_in *)&req.ifr_addr;
+ *mask = *ip_mask;
+ mask->sin_family = AF_INET;
+
+ return(0);
+}
+
+
+/*
+ * Get an interface's MTU
+ *
+ * Arguments:
+ * intf pointer to an interface name
+ * mtu pointer to an int to receive the MTU
+ *
+ * Returns:
+ * >= 0 interface MTU
+ * -1 error
+ *
+ */
+int
+get_mtu(intf)
+ char *intf;
+{
+ int rc, s;
+ struct ifreq req;
+
+ /*
+ * Check parameters
+ */
+ if (!intf || strlen(intf) == 0 ||
+ strlen(intf) > IFNAMSIZ-1)
+ return(-1);
+
+ /*
+ * Open a socket for the IOCTL
+ */
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ return(-1);
+
+ /*
+ * Set up and issue the IOCTL
+ */
+ UM_ZERO(&req, sizeof(req));
+ strcpy(req.ifr_name, intf);
+ rc = ioctl(s, SIOCGIFMTU, (caddr_t)&req);
+ (void)close(s);
+
+ /*
+ * Set the appropriate return value
+ */
+ if (rc)
+ return(-1);
+ else
+ return(req.ifr_mtu);
+}
+
+
+/*
+ * Verify netif name
+ *
+ * This routine issues an IOCTL to check whether the passed string is
+ * a valid network interface name.
+ *
+ * Arguments:
+ * req pointer to an ATM information request IOCTL structure
+ *
+ * Returns:
+ * -1 error encountered
+ * FALSE (0) the string is not a NIF name
+ * TRUE (> 0) the string is a valid NIF name
+ *
+ */
+int
+verify_nif_name(name)
+ char *name;
+{
+ int rc, s;
+ caddr_t buf;
+ struct atminfreq air;
+ struct air_netif_rsp *nif_info;
+
+ /*
+ * Check whether name is of a valid length
+ */
+ if (strlen(name) > IFNAMSIZ - 1 ||
+ strlen(name) < 1) {
+ return(FALSE);
+ }
+
+ /*
+ * Open a socket for the IOCTL
+ */
+ s = socket(AF_ATM, SOCK_DGRAM, 0);
+ if (s < 0) {
+ return(-1);
+ }
+
+ /*
+ * Get memory for returned information
+ */
+ nif_info = (struct air_netif_rsp *)UM_ALLOC(
+ sizeof(struct air_netif_rsp));
+ if (nif_info == NULL) {
+ errno = ENOMEM;
+ return(-1);
+ }
+
+ /*
+ * Set up the request
+ */
+ air.air_opcode = AIOCS_INF_NIF;
+ air.air_buf_addr = (caddr_t)nif_info;
+ air.air_buf_len = sizeof(struct air_netif_rsp);
+ UM_ZERO(air.air_netif_intf, sizeof(air.air_netif_intf));
+ strcpy(air.air_netif_intf, name);
+
+ /*
+ * Issue the IOCTL
+ */
+ rc = ioctl(s, AIOCINFO, (caddr_t)&air);
+ UM_FREE(nif_info);
+ (void)close(s);
+
+ /*
+ * Base return value on IOCTL return code
+ */
+ if (rc)
+ return(FALSE);
+ else
+ return(TRUE);
+}
+
+/*
+ * Get Config information
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ * cfgp pointer to a pointer to a struct air_cfg_rsp for the
+ * address of the returned Config information
+ *
+ * Returns:
+ * int length of returned Config information
+ *
+ */
+int
+get_cfg_info ( intf, cfgp )
+ char *intf;
+ struct air_cfg_rsp **cfgp;
+{
+ int buf_len = sizeof(struct air_cfg_rsp) * 4;
+ struct atminfreq air;
+
+ /*
+ * Initialize IOCTL request
+ */
+ air.air_opcode = AIOCS_INF_CFG;
+ UM_ZERO ( air.air_cfg_intf, sizeof(air.air_cfg_intf));
+ if ( intf != NULL && strlen(intf) != 0 )
+ strcpy ( air.air_cfg_intf, intf );
+
+ buf_len = do_info_ioctl ( &air, buf_len );
+
+ /*
+ * Return a pointer to the Config info and its length
+ */
+ *cfgp = (struct air_cfg_rsp *) air.air_buf_addr;
+ return ( buf_len );
+
+}
+
+/*
+ * Get Physical Interface information
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ * intp pointer to a pointer to a struct air_cfg_rsp for the
+ * address of the returned Config information
+ *
+ * Returns:
+ * int length of returned Config information
+ *
+ */
+int
+get_intf_info ( intf, intp )
+ char *intf;
+ struct air_int_rsp **intp;
+{
+ int buf_len = sizeof(struct air_int_rsp) * 4;
+ struct atminfreq air;
+
+ /*
+ * Initialize IOCTL request
+ */
+ air.air_opcode = AIOCS_INF_INT;
+ UM_ZERO ( air.air_int_intf, sizeof(air.air_int_intf));
+ if ( intf != NULL && strlen(intf) != 0 )
+ strcpy ( air.air_int_intf, intf );
+
+ buf_len = do_info_ioctl ( &air, buf_len );
+
+ /*
+ * Return a pointer to the Physical Interface info and its length
+ */
+ *intp = (struct air_int_rsp *) air.air_buf_addr;
+ return ( buf_len );
+
+}
+
+
+/*
+ * Get Netif information
+ *
+ * Arguments:
+ * intf pointer to interface name (or null string)
+ * netp pointer to a pointer to a struct air_netif_rsp for the
+ * address of the returned Netif information
+ *
+ * Returns:
+ * int length of returned Netif information
+ *
+ */
+int
+get_netif_info ( intf, netp )
+ char *intf;
+ struct air_netif_rsp **netp;
+{
+ int buf_len = sizeof(struct air_netif_rsp) * 10;
+ struct atminfreq air;
+
+ /*
+ * Initialize IOCTL request
+ */
+ air.air_opcode = AIOCS_INF_NIF;
+ UM_ZERO ( air.air_int_intf, sizeof(air.air_int_intf) );
+ if ( intf != NULL && strlen(intf) != 0 )
+ strcpy ( air.air_int_intf, intf );
+
+ buf_len = do_info_ioctl ( &air, buf_len );
+
+ /*
+ * Return a pointer to the Netif info and its length
+ */
+ *netp = (struct air_netif_rsp *) air.air_buf_addr;
+ return ( buf_len );
+
+}
+
+
OpenPOWER on IntegriCloud