9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER START
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * The contents of this file are subject to the terms of the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Common Development and Distribution License (the "License").
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You may not use this file except in compliance with the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * or http://www.opensolaris.org/os/licensing.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * See the License for the specific language governing permissions
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * and limitations under the License.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * When distributing Covered Code, include this CDDL HEADER in each
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * If applicable, add the following below this CDDL HEADER, with the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * CDDL HEADER END
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
1cfa752f4e24c34133009b0f6c139127a5c461deRamaswamy Tummala * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * MODULE: dapl_name_service.c
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * PURPOSE: Provide simple, file base name services in the absence
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * of DNS hooks for a particular transport type. If an
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * InfiniBand implementation supports IPoIB, this should
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * not be used.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Description: Interfaces in this file are completely described in
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * dapl_name_service.h
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Include files for setting up a network name
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include "dapl.h"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include "dapl_name_service.h"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <netinet/in.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <sys/sockio.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <net/if.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <net/if_dl.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <net/if_arp.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <net/if_types.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <arpa/inet.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <poll.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#include <ibd/ibd.h>
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifdef IBHOSTS_NAMING
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#define MAP_FILE "/etc/dapl/ibhosts"
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#define MAX_GID_ENTRIES 32
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAPL_GID_MAP g_gid_map_table[MAX_GID_ENTRIES];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN dapli_ns_create_gid_map(void);
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN dapli_ns_add_address(IN DAPL_GID_MAP *gme);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif /* IBHOSTS_NAMING */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * dapls_ns_init
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Initialize naming services
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Input:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * none
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Output:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * none
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Returns:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_SUCCESS
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_INVALID_PARAMETER
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_init(void)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DAT_RETURN dat_status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dat_status = DAT_SUCCESS;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifdef IBHOSTS_NAMING
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dat_status = dapli_ns_create_gid_map();
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif /* IBHOSTS_NAMING */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (dat_status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#ifdef IBHOSTS_NAMING
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * dapls_create_gid_map()
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Read /usr/local/etc/ibhosts to obtain host names and GIDs.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Create a table containing IP addresses and GIDs which can
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * be used for lookups.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * This implementation is a simple method providing name services
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * when more advanced mechanisms do not exist. The proper way
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * to obtain these mappings is to use a name service such as is
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * provided by IPoIB on InfiniBand.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Input:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * device_name Name of device as reported by the provider
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Output:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * none
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Returns:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * char * to string number
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapli_ns_create_gid_map(void)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor FILE *f;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_gid_t gid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor char hostname[128];
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int rc;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct addrinfo *addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_in *si;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DAPL_GID_MAP gmt;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor f = fopen(MAP_FILE, "r");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (f == NULL) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ERROR: Must have file <%s> "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "for IP/GID mappings\n", MAP_FILE);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_ERROR(DAT_INTERNAL_ERROR, 0));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rc = fscanf(f, "%s " F64x " " F64x, hostname,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &gid.gid_prefix, &gid.gid_guid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor while (rc != EOF) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rc = dapls_osd_getaddrinfo(hostname, &addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (rc != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * hostname not registered in DNS,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * provide a dummy value
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "WARNING: <%s> not registered in "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "DNS, using dummy IP value\n", hostname);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gmt.ip_address = 0x01020304;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Load into the ip/gid mapping table
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor si = (struct sockaddr_in *)addr->ai_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (AF_INET == addr->ai_addr->sa_family) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gmt.ip_address = si->sin_addr.s_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "WARNING: <%s> Address family "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "not supported, using dummy "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "IP value\n", hostname);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gmt.ip_address = 0x01020304;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapls_osd_freeaddrinfo(addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gmt.gid.gid_prefix = gid.gid_prefix;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gmt.gid.gid_guid = gid.gid_guid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapli_ns_add_address(&gmt);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor rc = fscanf(f, "%s " F64x " " F64x, hostname,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &gid.gid_prefix, &gid.gid_guid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) fclose(f);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * dapli_ns_add_address
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Add a table entry to the gid_map_table.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Input:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * remote_ia_address remote IP address
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gid pointer to output gid
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Output:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gid filled in GID
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Returns:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_SUCCESS
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_INSUFFICIENT_RESOURCES
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_INVALID_PARAMETER
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapli_ns_add_address(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAPL_GID_MAP *gme)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DAPL_GID_MAP *gmt;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int count;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gmt = g_gid_map_table;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (count = 0, gmt = g_gid_map_table; gmt->ip_address; gmt++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor count++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (count > MAX_GID_ENTRIES) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *gmt = *gme;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * dapls_ns_lookup_address
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Look up the provided IA_ADDRESS in the gid_map_table. Return
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the gid if found.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Input:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * remote_ia_address remote IP address
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gid pointer to output gid
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * timeout timeout in microseconds
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Output:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gid filled in GID
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Returns:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_SUCCESS
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_INSUFFICIENT_RESOURCES
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_INVALID_PARAMETER
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_lookup_address(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAPL_IA *ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAT_IA_ADDRESS_PTR remote_ia_address,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAT_TIMEOUT timeout,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor OUT ib_gid_t *gid)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DAPL_GID_MAP *gmt;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_in *si;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* unused here */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ia_ptr = ia_ptr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor si = (struct sockaddr_in *)remote_ia_address;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (gmt = g_gid_map_table; gmt->ip_address; gmt++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (gmt->ip_address == si->sin_addr.s_addr) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gid->gid_guid = gmt->gid.gid_guid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gid->gid_prefix = gmt->gid.gid_prefix;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_ERROR(DAT_INVALID_PARAMETER, 0));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#endif /* IBHOSTS_NAMING */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * utility function for printing a socket
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorchar *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_inet_ntop(struct sockaddr *addr, char *buf, size_t len)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor void *addr_ptr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (addr->sa_family == AF_INET) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr_ptr = (void *)&((struct sockaddr_in *)addr)->sin_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (addr->sa_family == AF_INET6) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor addr_ptr = (void *)&((struct sockaddr_in6 *)addr)->sin6_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (len > strlen("bad address")) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) sprintf(buf, "bad address");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (buf);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return ((char *)inet_ntop(addr->sa_family, addr_ptr, buf, len));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor/*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * dapls_ns_lookup_address
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * translates an IP address into a GID
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Input:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * ia_ptr pointer to IA object
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * remote_ia_address remote IP address
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gid pointer to output gid
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * timeout timeout in microseconds
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Output:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gid filled in GID
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor *
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * Returns:
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_SUCCESS
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_INVALID_ADDRRESS
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_INVALID_PARAMETER
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * DAT_INTERNAL_ERROR
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor#define NS_MAX_RETRIES 60
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_lookup_v4(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAPL_IA *ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN struct sockaddr_in *addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAT_TIMEOUT timeout,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor OUT ib_gid_t *gid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_lookup_v6(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAPL_IA *ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN struct sockaddr_in6 *addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAT_TIMEOUT timeout,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor OUT ib_gid_t *gid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int dapls_ns_subnet_match_v4(int s, DAPL_IA *ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_in *addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int dapls_ns_subnet_match_v6(int s, DAPL_IA *ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_in6 *addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int dapls_ns_send_packet_v6(int s, struct sockaddr_in6 *addr);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int dapls_ns_resolve_addr(int af, struct sockaddr *addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DAT_TIMEOUT timeout);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_lookup_address(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAPL_IA *ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAT_IA_ADDRESS_PTR remote_ia_address,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAT_TIMEOUT timeout,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor OUT ib_gid_t *gid)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DAT_RETURN dat_status;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr *sock = (struct sockaddr *)remote_ia_address;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (sock->sa_family == AF_INET) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dat_status = dapls_ns_lookup_v4(ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (struct sockaddr_in *)sock, timeout, gid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (sock->sa_family == AF_INET6) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dat_status = dapls_ns_lookup_v6(ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (struct sockaddr_in6 *)sock, timeout, gid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dat_status = DAT_INVALID_PARAMETER;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (dat_status);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_lookup_v4(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAPL_IA *ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN struct sockaddr_in *addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAT_TIMEOUT timeout,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor OUT ib_gid_t *gid)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct xarpreq ar;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_in *sin;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uchar_t *mac;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int s, retries = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) dapl_os_memzero(&ar, sizeof (ar));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sin = (struct sockaddr_in *)&ar.xarp_pa;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sin->sin_family = AF_INET;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sin->sin_addr.s_addr = addr->sin_addr.s_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ar.xarp_ha.sdl_family = AF_LINK;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor s = socket(AF_INET, SOCK_DGRAM, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (s < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_lookup_v4: socket: %s\n", strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_INTERNAL_ERROR);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (dapls_ns_subnet_match_v4(s, ia_ptr, addr) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(s);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_INVALID_ADDRESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloragain:;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(s, SIOCGXARP, (caddr_t)&ar) < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * if SIOCGXARP failed, we force the ARP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * cache to be filled by connecting to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * destination IP address.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retries <= NS_MAX_RETRIES &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapls_ns_resolve_addr(AF_INET, (struct sockaddr *)addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor timeout) == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retries++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto again;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ns_lookup_v4: giving up\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(s);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_ERROR(DAT_INVALID_ADDRESS,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DAT_INVALID_ADDRESS_UNREACHABLE));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if ((ar.xarp_flags & ATF_COM) == 0 &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ar.xarp_ha.sdl_type == IFT_IB && retries <= NS_MAX_RETRIES) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we get here if arp resolution is still incomplete
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retries++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) sleep(1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto again;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(s);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mac = (uchar_t *)LLADDR(&ar.xarp_ha);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ar.xarp_flags & ATF_COM &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ar.xarp_ha.sdl_type == IFT_IB &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ar.xarp_ha.sdl_alen >= sizeof (ipoib_mac_t)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_gid_t tmp_gid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) dapl_os_memcpy(&tmp_gid,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &((ipoib_mac_t *)mac)->ipoib_gidpref, sizeof (ib_gid_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gids from the ARP table are in network order, convert
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the gids from network order to host byte order
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gid->gid_prefix = BETOH_64(tmp_gid.gid_prefix);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gid->gid_guid = BETOH_64(tmp_gid.gid_guid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, len;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor len = ar.xarp_ha.sdl_alen;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_lookup_v4: failed, non IB address: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "len = %d, addr = 0x", len);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (len > 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < len; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%02x", (int)mac[i] & 0xff);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR, "0");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR, "\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_INVALID_ADDRESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill TaylorDAT_RETURN
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_lookup_v6(
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAPL_IA *ia_ptr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN struct sockaddr_in6 *addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor IN DAT_TIMEOUT timeout,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor OUT ib_gid_t *gid)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct lifreq lifr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uchar_t *mac;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int s, retries = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor s = socket(AF_INET6, SOCK_DGRAM, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (s < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_lookup_v6: socket: %s\n", strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_INTERNAL_ERROR);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (dapls_ns_subnet_match_v6(s, ia_ptr, addr) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(s);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_INVALID_ADDRESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) dapl_os_memzero(&lifr, sizeof (lifr));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) dapl_os_memcpy(&lifr.lifr_nd.lnr_addr, addr, sizeof (*addr));
1cfa752f4e24c34133009b0f6c139127a5c461deRamaswamy Tummala (void) dapl_os_strcpy(lifr.lifr_name, ia_ptr->hca_ptr->name);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Tayloragain:;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (ioctl(s, SIOCLIFGETND, (caddr_t)&lifr) < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * if SIOCLIFGETND failed, we force the ND
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * cache to be filled by connecting to the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * destination IP address.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retries < NS_MAX_RETRIES &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapls_ns_send_packet_v6(s, addr) == 0 &&
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapls_ns_resolve_addr(AF_INET6, (struct sockaddr *)addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor timeout) == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retries++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto again;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR, "ns_lookup_v6: giving up\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(s);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_ERROR(DAT_INVALID_ADDRESS,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor DAT_INVALID_ADDRESS_UNREACHABLE));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (lifr.lifr_nd.lnr_hdw_len == 0 && retries <= NS_MAX_RETRIES) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * lnr_hdw_len == 0 means that the ND entry
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * is still incomplete. we need to retry the ioctl.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retries++;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) sleep(1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor goto again;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(s);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor mac = (uchar_t *)lifr.lifr_nd.lnr_hdw_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (lifr.lifr_nd.lnr_hdw_len >= sizeof (ipoib_mac_t)) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ib_gid_t tmp_gid;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) dapl_os_memcpy(&tmp_gid,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &((ipoib_mac_t *)mac)->ipoib_gidpref, sizeof (ib_gid_t));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * gids from the ND table are in network order, convert
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * the gids from network order to host byte order
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gid->gid_prefix = BETOH_64(tmp_gid.gid_prefix);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor gid->gid_guid = BETOH_64(tmp_gid.gid_guid);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, len;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor len = lifr.lifr_nd.lnr_hdw_len;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_lookup_v6: failed, non IB address: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "len = %d, addr = 0x", len);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (len > 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < len; i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "%02x", (int)mac[i] & 0xff);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR, "0");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR, "\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_INVALID_ADDRESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (DAT_SUCCESS);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_send_packet_v6(int s, struct sockaddr_in6 *addr)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (sendto(s, NULL, 0, MSG_DONTROUTE, (struct sockaddr *)addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (*addr)) < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_send_packet_v6: failed: %s\n", strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_subnet_match_v4(int s, DAPL_IA *ia_ptr, struct sockaddr_in *addr)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct lifreq lifreq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int retval;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uint32_t netmask, netaddr, netaddr_dest;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
1cfa752f4e24c34133009b0f6c139127a5c461deRamaswamy Tummala (void) dapl_os_strcpy(lifreq.lifr_name, ia_ptr->hca_ptr->name);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifreq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_subnet_match_v4: cannot get netmask: %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor netmask = ((struct sockaddr_in *)&lifreq.lifr_addr)->
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sin_addr.s_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we need to get the interface address here because the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * address in ia_ptr->hca_ptr->hca_address might not
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * necessarily be an IPv4 address.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = ioctl(s, SIOCGLIFADDR, (caddr_t)&lifreq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_subnet_match_v4: cannot get local addr: %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor netaddr = ((struct sockaddr_in *)&lifreq.lifr_addr)->
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sin_addr.s_addr & netmask;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor netaddr_dest = addr->sin_addr.s_addr & netmask;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (netaddr != netaddr_dest) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_subnet_match_v4: netaddrs don't match: "
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "local %x, remote %x\n", netaddr, netaddr_dest);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_subnet_match_v6(int s, DAPL_IA *ia_ptr, struct sockaddr_in6 *addr)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct lifreq lifreq;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_in6 netmask_sock;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor uchar_t *netmask, *local_addr, *dest_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int i, retval;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
1cfa752f4e24c34133009b0f6c139127a5c461deRamaswamy Tummala (void) dapl_os_strcpy(lifreq.lifr_name, ia_ptr->hca_ptr->name);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifreq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_subnet_match_v6: cannot get netmask: %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) dapl_os_memcpy(&netmask_sock, &lifreq.lifr_addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (netmask_sock));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we need to get the interface address here because the
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * address in ia_ptr->hca_ptr->hca_address might not
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * necessarily be an IPv6 address.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = ioctl(s, SIOCGLIFADDR, (caddr_t)&lifreq);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_subnet_match_v6: cannot get local addr: %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor netmask = (uchar_t *)&netmask_sock.sin6_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor local_addr = (uchar_t *)&((struct sockaddr_in6 *)&lifreq.lifr_addr)->
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sin6_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dest_addr = (uchar_t *)&addr->sin6_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor for (i = 0; i < sizeof (addr->sin6_addr); i++) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (((local_addr[i] ^ dest_addr[i]) & netmask[i]) != 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_subnet_match_v6: subnets do not match\n");
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylorstatic int
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylordapls_ns_resolve_addr(int af, struct sockaddr *addr, DAT_TIMEOUT timeout)
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor{
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_storage sock;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_in *v4dest;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct sockaddr_in6 *v6dest;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor struct pollfd pollfd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int fd, retval;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int tmo;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int ip_version;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (af == AF_INET) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ip_version = 4;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else if (af == AF_INET6) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ip_version = 6;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_resolve_addr: invalid af %d\n", af);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor fd = socket(af, SOCK_STREAM, 0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (fd < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_resolve_addr: ipv%d, cannot create socket %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ip_version, strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * set socket to non-blocking mode
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = fcntl(fd, F_SETFL, O_NONBLOCK);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval < 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_resolve_addr: ipv%d, fcntl failed: %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ip_version, strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(fd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (-1);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * connect to the discard port (9) at the dest IP
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) dapl_os_memzero(&sock, sizeof (sock));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (af == AF_INET) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor v4dest = (struct sockaddr_in *)&sock;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor v4dest->sin_family = AF_INET;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor v4dest->sin_addr.s_addr =
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ((struct sockaddr_in *)addr)->sin_addr.s_addr;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor v4dest->sin_port = htons(9);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = connect(fd, (struct sockaddr *)v4dest,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (struct sockaddr_in));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor v6dest = (struct sockaddr_in6 *)&sock;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor v6dest->sin6_family = AF_INET6;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) dapl_os_memcpy(&v6dest->sin6_addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &((struct sockaddr_in6 *)addr)->sin6_addr,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (struct sockaddr_in6));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor v6dest->sin6_port = htons(9);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = connect(fd, (struct sockaddr *)v6dest,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor sizeof (struct sockaddr_in6));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we can return immediately if connect succeeds
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(fd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * receiving a RST means that the arp/nd entry should
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * already be resolved
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval < 0 && errno == ECONNREFUSED) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor errno = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(fd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (0);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * for all other cases, we poll on the fd
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pollfd.fd = fd;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pollfd.events = POLLIN | POLLOUT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor pollfd.revents = 0;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (timeout == DAT_TIMEOUT_INFINITE ||
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor timeout == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * -1 means infinite
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmo = -1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * convert timeout from usecs to msecs
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor tmo = timeout/1000;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = poll(&pollfd, 1, tmo);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval > 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor int so_error = 0, len = sizeof (so_error);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = getsockopt(fd, SOL_SOCKET, SO_ERROR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor &so_error, &len);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * we only return 0 if so_error == 0 or
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * so_error == ECONNREFUSED. for all other
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * cases retval is non-zero.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (so_error != 0 && so_error != ECONNREFUSED) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = -1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor errno = so_error;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_resolve_addr: ipv%d, so_error: %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ip_version, strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor /*
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * if retval != 0, it must be -1. and errno must
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor * have been set by getsockopt.
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor */
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_resolve_addr: ipv%d, getsockopt: %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ip_version, strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor } else {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor if (retval == 0) {
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor errno = ETIMEDOUT;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor retval = -1;
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor "ns_resolve_addr: ipv%d, poll: %s\n",
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor ip_version, strerror(errno));
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor }
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor (void) close(fd);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor return (retval);
9e39c5ba00a55fa05777cc94b148296af305e135Bill Taylor}