--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/visual-panels/core/src/cmd/rad/mod/network/mod_network.c Thu May 24 04:16:47 2012 -0400
@@ -0,0 +1,264 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <stropts.h>
+#include <sys/conf.h>
+#include <net/if.h>
+#include <sys/sockio.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include <rad/adr.h>
+#include <rad/rad_modapi.h>
+
+#include "api_network.h"
+
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+
+static int
+if_count(int fd, int *count)
+{
+ struct lifnum ifnum;
+
+ ifnum.lifn_family = AF_INET;
+ ifnum.lifn_flags = 0;
+ if (ioctl(fd, SIOCGLIFNUM, &ifnum) == -1) {
+ (void) close(fd);
+ return (-1);
+ }
+
+ *count = ifnum.lifn_count;
+ return (0);
+}
+
+/* ARGSUSED */
+conerr_t
+interface_Network_read_networkInterfaces(rad_instance_t *inst,
+ adr_attribute_t *attr, data_t **data, data_t **error)
+{
+ int fd;
+ int count, rcount;
+ int reqsize;
+ struct lifreq *reqs = NULL;
+ struct lifconf ifconf;
+ data_t *result;
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ return (ce_object);
+
+ do {
+ if (reqs != NULL)
+ free(reqs);
+
+ if (if_count(fd, &count) == -1)
+ return (ce_object);
+
+ if (count == 0) {
+ (void) close(fd);
+ *data = data_new_array(&t_array_string, 0);
+ return (ce_ok);
+ }
+
+ count += 5;
+ reqsize = count * sizeof (struct lifreq);
+ if ((reqs = malloc(reqsize)) == NULL) {
+ (void) close(fd);
+ return (ce_object);
+ }
+
+ ifconf.lifc_family = AF_INET;
+ ifconf.lifc_len = reqsize;
+ ifconf.lifc_buf = (char *)reqs;
+ ifconf.lifc_flags = 0;
+ if (ioctl(fd, SIOCGLIFCONF, &ifconf) == -1) {
+ (void) close(fd);
+ free(reqs);
+ return (ce_object);
+ }
+ rcount = ifconf.lifc_len / sizeof (struct lifreq);
+ } while (rcount >= count);
+
+ result = data_new_array(&t_array_string, rcount);
+ for (int i = 0; i < rcount; i++) {
+ struct lifreq *r = &ifconf.lifc_req[i];
+ if (strchr(r->lifr_name, ':') != NULL)
+ continue;
+ if (ioctl(fd, SIOCGLIFFLAGS, r) == -1)
+ continue;
+ if ((r->lifr_flags & (IFF_LOOPBACK | IFF_VIRTUAL)) != 0)
+ continue;
+ (void) array_add(result, data_new_string(r->lifr_name,
+ lt_copy));
+ }
+ (void) close(fd);
+ free(reqs);
+
+ *data = data_purify_deep(result);
+ return (ce_ok);
+}
+
+/* ARGSUSED */
+conerr_t
+interface_Network_invoke_getHostNameForIP(rad_instance_t *inst,
+ adr_method_t *meth, data_t **ret, data_t **args, int count, data_t **error)
+{
+ int errnum;
+ struct hostent *he;
+ ipaddr_t addr;
+
+ if (inet_pton(AF_INET, data_to_string(args[0]), &addr) != 1)
+ return (ce_object);
+
+ if ((he = getipnodebyaddr(&addr, sizeof (addr), AF_INET, &errnum))
+ == NULL) {
+ /* Not found? Bounce it back. */
+ (void) data_ref(args[0]);
+ *ret = args[0];
+ return (ce_ok);
+ }
+
+ data_t *result = data_new_string(he->h_name, lt_copy);
+ freehostent(he);
+ *ret = result;
+
+ return (ce_ok);
+}
+
+/* ARGSUSED */
+conerr_t
+interface_Network_invoke_hostGetIPs(rad_instance_t *inst, adr_method_t *meth,
+ data_t **ret, data_t **args, int count, data_t **error)
+{
+ int errnum;
+ struct hostent *he;
+
+ if ((he = getipnodebyname(data_to_string(args[0]), AF_INET, AI_DEFAULT,
+ &errnum)) == NULL) {
+ *ret = NULL;
+ return (ce_object);
+ }
+
+ int n = 0;
+ for (char **aptr = he->h_addr_list; *aptr != NULL; aptr++)
+ n++;
+ data_t *result = data_new_array(&t_array_string, n);
+ for (int i = 0; i < n; i++) {
+ char abuf[INET_ADDRSTRLEN];
+ if (inet_ntop(AF_INET, he->h_addr_list[i], abuf,
+ sizeof (abuf)) != NULL)
+ (void) array_add(result, data_new_string(abuf,
+ lt_copy));
+ }
+
+ *ret = data_purify_deep(result);
+ freehostent(he);
+
+ return (ce_ok);
+}
+
+/* ARGSUSED */
+conerr_t
+interface_Network_invoke_isLocalAddress(rad_instance_t *inst,
+ adr_method_t *meth, data_t **ret, data_t **args, int count, data_t **error)
+{
+ struct ifaddrs *ifaddr;
+ struct ifaddrs *ifa;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ char buf[1024];
+ (void) memset(buf, 0, sizeof (buf));
+
+ /* Set default return value */
+ *ret = data_new_boolean(B_FALSE);
+
+ // Get IP addresses of each network interface.
+ //
+ // ifa_name ifa_addr->sin_addr.s_addr
+ //
+ // lo0 0.0.0.0
+ // lo0 ::1 (AF_INET6)
+ // lo0 127.0.0.1 (AF_INET)
+ // e1000g0 129.XXX.XXX.XXX (AF_INET)
+ //
+ // See: man -s3 socket getifaddrs
+ if (getifaddrs(&ifaddr) == -1) {
+ return (ce_object);
+ }
+
+ /* Iterate over linked list of IP addresses */
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_flags & IFF_IPV4) {
+ /* LINTED */
+ sin = (struct sockaddr_in *)ifa->ifa_addr;
+
+ /* Match given IP address */
+ if (strcmp(data_to_string(args[0]), inet_ntop(AF_INET,
+ &sin->sin_addr.s_addr, buf, 1024)) == 0) {
+ *ret = data_new_boolean(B_TRUE);
+ break;
+ }
+ } else {
+ /* LINTED */
+ sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+
+ /* Match given IP address */
+ if (strcmp(data_to_string(args[0]), inet_ntop(AF_INET6,
+ &sin6->sin6_addr.s6_addr, buf, 1024)) == 0) {
+ *ret = data_new_boolean(B_TRUE);
+ break;
+ }
+ }
+ }
+ freeifaddrs(ifaddr);
+ return (ce_ok);
+}
+
+static rad_modinfo_t modinfo = { "network", "Network panel support" };
+
+int
+_rad_init(void *handle)
+{
+ if (rad_module_register(handle, RAD_MODVERSION, &modinfo) == -1)
+ return (-1);
+
+ if (rad_isproxy)
+ return (0);
+
+ (void) cont_insert_singleton(rad_container, adr_name_fromstr(
+ "com.oracle.solaris.vp.panel.common.api.network:type=Network"),
+ &interface_Network_svr);
+
+ return (0);
+}