summaryrefslogtreecommitdiffstats
path: root/contrib/ofed/libsdp
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2011-03-21 09:58:24 +0000
committerjeff <jeff@FreeBSD.org>2011-03-21 09:58:24 +0000
commit5115240a6cdc054f7eea804355742f97c74578d8 (patch)
tree3051c12f4ce44a65c025b72ec5821b35b2ec46be /contrib/ofed/libsdp
parent2d7d8c05e7404fbebf1f0fe24c13bc5bb58d2338 (diff)
downloadFreeBSD-src-5115240a6cdc054f7eea804355742f97c74578d8.zip
FreeBSD-src-5115240a6cdc054f7eea804355742f97c74578d8.tar.gz
- Merge in OFED 1.5.3 from projects/ofed/head
Diffstat (limited to 'contrib/ofed/libsdp')
-rw-r--r--contrib/ofed/libsdp/COPYING36
-rw-r--r--contrib/ofed/libsdp/ChangeLog96
-rw-r--r--contrib/ofed/libsdp/Makefile.am23
-rw-r--r--contrib/ofed/libsdp/NEWS4
-rw-r--r--contrib/ofed/libsdp/README68
-rwxr-xr-xcontrib/ofed/libsdp/autogen.sh8
-rwxr-xr-xcontrib/ofed/libsdp/changelog_from_git.sh3
-rwxr-xr-xcontrib/ofed/libsdp/config/libsdp_indent71
-rw-r--r--contrib/ofed/libsdp/configure.in59
-rw-r--r--contrib/ofed/libsdp/libsdp.conf139
-rw-r--r--contrib/ofed/libsdp/libsdp.spec.in55
-rw-r--r--contrib/ofed/libsdp/src/Makefile.am29
-rw-r--r--contrib/ofed/libsdp/src/config_parser.c1890
-rw-r--r--contrib/ofed/libsdp/src/config_parser.h95
-rw-r--r--contrib/ofed/libsdp/src/config_scanner.c1885
-rw-r--r--contrib/ofed/libsdp/src/libsdp.h131
-rw-r--r--contrib/ofed/libsdp/src/linux/sdp_inet.h52
-rw-r--r--contrib/ofed/libsdp/src/log.c236
-rw-r--r--contrib/ofed/libsdp/src/match.c296
-rw-r--r--contrib/ofed/libsdp/src/port.c2629
-rw-r--r--contrib/ofed/libsdp/src/socket.c167
21 files changed, 7972 insertions, 0 deletions
diff --git a/contrib/ofed/libsdp/COPYING b/contrib/ofed/libsdp/COPYING
new file mode 100644
index 0000000..fac7531
--- /dev/null
+++ b/contrib/ofed/libsdp/COPYING
@@ -0,0 +1,36 @@
+This software is available to you under a choice of one of two
+licenses. You may choose to be licensed under the terms of the GNU
+General Public License (GPL) Version 2, available at
+<http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
+license, included below.
+
+Copyright (c) 2004 Topspin Communications. All rights reserved.
+Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
+
+
+OpenIB.org BSD license:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/contrib/ofed/libsdp/ChangeLog b/contrib/ofed/libsdp/ChangeLog
new file mode 100644
index 0000000..d38dc69
--- /dev/null
+++ b/contrib/ofed/libsdp/ChangeLog
@@ -0,0 +1,96 @@
+2010-12-26 18:14:02 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 9c2ad15 libsdp: full ipv6 support
+
+2010-11-29 11:43:51 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 0a3d5c3 libsdp: BUG2130 - libsdp.so is not installed + version
+ 1.1.106
+2010-11-08 14:41:27 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 7a1880f libsdp: updated version to 1.1.105
+
+2010-11-08 14:31:13 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * c6efc06 libsdp: fix security issues with log file
+
+2010-11-02 15:28:06 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 09343d1 libsdp: fix bad permissions
+
+2010-10-28 13:46:39 +0200 root <root@swv300.lab.mtl.com>
+ * 46d845d libsdp: fixed indentation
+
+2010-10-04 11:49:46 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 59b6a36 libsdp: updated version to 1.1.104
+
+2010-10-04 11:22:23 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 21b63e0 libsdp: fix libsdp.so permissions
+
+2010-10-04 11:20:49 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 3180e25 libsdp: fix "make dist"
+
+2010-09-13 10:31:52 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * df744a5 libsdp: updated version to 1.1.103
+
+2010-09-13 10:45:40 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * e3ce469 libsdp: don't make libsdp depend on sdp_socket.h from ib-kernel
+
+2010-08-03 15:35:11 +0300 Amir Vadai <amirv@mellanox.co.il>
+ * c5ff8e2 libsdp: updated version to 1.1.102
+
+2010-08-03 15:33:57 +0300 Amir Vadai <amirv@mellanox.co.il>
+ * 82fe3f9 libsdp: search openib headers according to 'prefix'
+
+2010-04-11 11:38:47 +0300 Amir Vadai <amirv@mellanox.co.il>
+ * 76060c5 libsdp: changed version to 1.1.101
+
+2010-04-08 09:33:29 +0300 Eldad Zinger <eldadz@mellanox.co.il>
+ * 8bf57aa libsdp: added differentiation between bind failures of sdp.
+
+2010-03-23 10:13:45 +0200 Eldad Zinger <eldadz@mellanox.co.il>
+ * 93706ed sdp: BUG1984 - fix for bad memory access.
+
+2010-04-08 15:40:55 +0300 Amir Vadai <amirv@mellanox.co.il>
+ * dadef4b libsdp: add path to openib include's
+
+2010-02-18 11:04:29 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 920ea31 libsdp: changed version to 1.1.100
+
+2010-02-18 11:02:20 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 0fe8a11 libsdp: updated changelog from git + script to get change log
+
+2010-02-18 10:49:42 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * a298098 libsdp: Fix memory leak. free libsdp_fd_attributes
+
+2010-02-18 10:49:00 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * cf4ceab libsdp: make libsdp.so have gid bit on
+
+2008-11-26 13:44:26 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * b1eaecb libsdp: Enable building libsdp on Solaris
+
+2008-11-23 Amir Vadai <amirv@mellanox.co.il>
+ * BUG1405 - conflict when running an application that use yacc.
+
+2008-12-08 18:29:09 +0200 Yossi Etigin <yossi.openib@gmail.com>
+ * dcfca98 libsdp: BUG1256 - Add epoll support
+
+2008-11-23 16:09:21 +0200 Amir Vadai <amirv@mellanox.co.il>
+ * 02404fb libsdp: BUG1405 - conflict when running an application that use yacc.
+
+2008-09-02 15:13:22 +0300 Yossi Etigin <[yossi.openib@gmail.com]>
+ * 64adc0e libsdp: enable fallback to TCP for nonblocking sockets
+
+2008-08-21 10:52:19 +0300 Yossi Etigin <[yossi.openib@gmail.com]>
+ * cee8053 libsdp: write fcntl argument in debug prints
+
+2008-07-21 22:01:21 +0300 Amir Vadai <amirv@mellanox.co.il>
+ * 81d6ec3 removed not unnecessary use of va_copy.
+
+2008-06-12 14:13:07 +0300 Amir Vadai <amirv@mellanox.co.il>
+ * 90f25b7 Fixed compilation error on Fedora Release 9
+
+2006-05-29 Eitan Zahavi <eitan@mellanox.co.il>
+
+ * Support IPv4 embedded in IPv6 addresses. Since SDP currently does
+ not support IPv6 we need to convert to IPv4 and back on queries.
+
+ * port.c - cleanup abnd re-written for clearer flow. Added verbose
+ messages.
+
+ * Major re-write of the parser to support new syntax and using BNF
diff --git a/contrib/ofed/libsdp/Makefile.am b/contrib/ofed/libsdp/Makefile.am
new file mode 100644
index 0000000..13c5680
--- /dev/null
+++ b/contrib/ofed/libsdp/Makefile.am
@@ -0,0 +1,23 @@
+SUBDIRS = src
+
+EXTRA_DIST = libsdp.spec.in libsdp.conf
+
+dist-hook: libsdp.spec
+ cp libsdp.spec $(distdir)
+
+install-data-hook:
+ if test -e $(DESTDIR)$(sysconfdir)/libsdp.conf; then \
+ diff -q $(srcdir)/libsdp.conf $(DESTDIR)$(sysconfdir)/libsdp.conf 1> /dev/null; \
+ if test $$? == 1; then \
+ t=$(shell date +'%Y%m%d%H%M%S'); \
+ cp -p $(srcdir)/libsdp.conf \
+ $(DESTDIR)$(sysconfdir)/libsdp.conf.$$t; \
+ echo "NOTE: existing libsdp.conf was not updated."; \
+ echo " libsdp.conf installed as ibsdp.conf.$$t instead."; \
+ fi; \
+ else \
+ if test ! -d $(DESTDIR)$(sysconfdir); then \
+ mkdir -p $(DESTDIR)$(sysconfdir); \
+ fi; \
+ cp -p $(srcdir)/libsdp.conf $(DESTDIR)$(sysconfdir)/libsdp.conf; \
+ fi
diff --git a/contrib/ofed/libsdp/NEWS b/contrib/ofed/libsdp/NEWS
new file mode 100644
index 0000000..1fb082b
--- /dev/null
+++ b/contrib/ofed/libsdp/NEWS
@@ -0,0 +1,4 @@
+0.9.0 - Initial release.
+1.0.0 - Following RFC for enhanced configuration semantics, strong parsing,
+ major cleanup, verbosity logging and thread safe code
+ \ No newline at end of file
diff --git a/contrib/ofed/libsdp/README b/contrib/ofed/libsdp/README
new file mode 100644
index 0000000..6499bbc
--- /dev/null
+++ b/contrib/ofed/libsdp/README
@@ -0,0 +1,68 @@
+LIBSDP - A User Level Socket Switch for Seemless Migration to SDP
+-----------------------------------------------------------------
+
+OVERVIEW:
+---------
+libsdp is a LD_PRELOAD-able library that can be used to migrate existing
+applications use InfiniBand Sockets Direct Protocol (SDP) instead of
+TCP sockets, transparently and without recompilations. To setup libsdp
+please follow the instructions below.
+
+SETUP:
+------
+libsdp.so isn't setup automatically. it can be used in one of 2 ways:
+1) LD_PRELOAD environment variable. Setting this to the name of the
+ library you want to use will cause it to be preloaded.
+2) Adding the name of the library into /etc/ld.so.preload. This will
+ cause the library to be preloaded for every executable that is linked
+ with libc.
+
+The library should be installed in a directory in which the dynamic loader
+searches for shared libraries (as specified by LD_LIBRARY_PATH,
+/etc/ld.so.conf, etc). Alternatively, you can specify the full path to the
+library that you want to use in LD_PRELOAD or /etc/ld.so.preload as described
+above.
+
+The last option cant be used if you have multiple library versions
+(e.g. 64/32 bit) and want the linker to select between them automatically.
+The best way to handle such case is to use LD_LIBRARY_PATH to point to both the
+lib (the 32 bit version) and lib64 directories and LD_RELOAD the libsdp.so.
+This way the correct 32/64bit libsdp.so will be selected.
+For example running ssh over SDP with OFED distribution from bash this can be written:
+LD_LIBRARY_PATH=/usr/local/ofed/lib64:/usr/local/ofed/lib LD_PRELOAD=libsdp.so ssh
+
+CONFIGURATION:
+--------------
+libsdp supports two modes of configuration:
+* simple operation where it converts all calls to socket(2) with a family
+ of AF_INET(6) and a type of SOCK_STREAM into family of AF_INET_SDP.
+* selective mode where it uses a configuration file to select which sockets
+ will be using SDP and which will not.
+
+For real world applications where communication with X, authentication,
+DNS and other servers connected through TCP is required the selective mode
+is required.
+
+Simple mode will be selected in one of the following conditions:
+* the environment variable SIMPLE_LIBSDP to a non-empty value
+* no configuration file is defined or is un-readble
+* the configuration file does not include any address family rule
+
+For information on how to configure libsdp, see libsdp.conf, which is installed
+in $(sysconfdir) (usually /usr/local/etc or /etc). The user can further control
+the file to be used for configuration by setting the environment variable:
+LIBSDP_CONFIG_FILE
+
+LIMITATIONS:
+------------
+1. Applications statically linked with libc will not allow dynamic pre-loading
+ to port these applications to use SDP one needs to replace specific socket
+ calls (within the application) with AF_INET_SDP and recompile.
+2. If for some reason the dynamic linker fail to pre-load libc before the
+ libsdp.so is initialized or it does not support RTDL_NEXT, libsdp will
+ fail to find the libc socket API. To overcome this situation a simple
+ implementation of hijacking "socket" call is provided in libsdp_sys.
+ This partial implementation does not support any configuration and is
+ limited to i386 architecture.
+3. Non-blocking connect in "both" mode defaults to SDP. Specific rules might be
+ needed for applications to operate properly.
diff --git a/contrib/ofed/libsdp/autogen.sh b/contrib/ofed/libsdp/autogen.sh
new file mode 100755
index 0000000..fd47839
--- /dev/null
+++ b/contrib/ofed/libsdp/autogen.sh
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+set -x
+aclocal -I config
+libtoolize --force --copy
+autoheader
+automake --foreign --add-missing --copy
+autoconf
diff --git a/contrib/ofed/libsdp/changelog_from_git.sh b/contrib/ofed/libsdp/changelog_from_git.sh
new file mode 100755
index 0000000..e3d86b2
--- /dev/null
+++ b/contrib/ofed/libsdp/changelog_from_git.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+git log --pretty=format:"%ai %an <%ae>%n * %h %s%n"
diff --git a/contrib/ofed/libsdp/config/libsdp_indent b/contrib/ofed/libsdp/config/libsdp_indent
new file mode 100755
index 0000000..6bae67d
--- /dev/null
+++ b/contrib/ofed/libsdp/config/libsdp_indent
@@ -0,0 +1,71 @@
+#!/bin/bash
+#
+# Copyright (c) 2006 Mellanox Technologies LTD. All rights reserved.
+#
+# This software is available to you under a choice of one of two
+# licenses. You may choose to be licensed under the terms of the GNU
+# General Public License (GPL) Version 2, available from the file
+# COPYING in the main directory of this source tree, or the
+# OpenIB.org BSD license below:
+#
+# Redistribution and use in source and binary forms, with or
+# without modification, are permitted provided that the following
+# conditions are met:
+#
+# - Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the following
+# disclaimer.
+#
+# - Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# $Id: osm_indent 4707 2006-01-03 16:18:08Z halr $
+#
+#########################################################################
+#
+# Abstract:
+# Indent script for enforcing source code formatting.
+#
+# This is the indent format used for libsdp:
+#
+# -bad Blank line after declarations
+# -bap Blank line after Procedures
+# -nbbb NO Blank line before block comments
+# -nbbo NO Break after Boolean operator
+# -bl Break after if line
+# -bli0 Indent for braces is 0
+# -bls Break after struct declarations
+# -cbi0 Case break indent 0
+# -ci3 Continue indent 3 spaces
+# -cli0 Case label indent 0 spaces
+# -ncs No space after cast operator
+# -hnl Honor existing newlines on long lines
+# -i3 Substitute indent with 3 spaces
+# -npcs No space after procedure calls
+# -prs Space after parenthesis
+# -nsai No space after if keyword - removed
+# -nsaw No space after while keyword - removed
+# -sc Put * at left of comments in a block comment style
+# -nsob Don't swallow unnecessary blank lines
+# -ts3 Tab size is 3
+# -psl Type of procedure return in a separate line
+# -bfda Function declaration arguments in a separate line.
+# -ut No tabs as we allow spaces
+# -br Put braces on line with if, etc
+# -ce Cuddle else and preceeding }
+#
+#########################################################################
+
+eval indent -bad -bap -nbbb -nbbo -bl -bli0 -bls -cbi0 -ci3 -cli0 -ncs \
+ -hnl -i3 -npcs -prs -sc -nsob -ts3 -psl -bfda -ut -br -ce $*
diff --git a/contrib/ofed/libsdp/configure.in b/contrib/ofed/libsdp/configure.in
new file mode 100644
index 0000000..b1f34a4
--- /dev/null
+++ b/contrib/ofed/libsdp/configure.in
@@ -0,0 +1,59 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+
+AC_PREREQ(2.57)
+AC_INIT(libsdp, 1.1.108, openib-general@openib.org)
+AC_CONFIG_SRCDIR([src/port.c])
+AC_CONFIG_AUX_DIR(config)
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(libsdp, 1.1.108)
+
+AC_CANONICAL_HOST
+AM_MAINTAINER_MODE
+
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_LEX
+AC_PROG_YACC
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([arpa/inet.h netinet/in.h stdlib.h string.h sys/socket.h syslog.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+# Checks for library functions.
+AC_REPLACE_FNMATCH
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_MALLOC
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([dup2 memset socket strcasecmp strchr strdup strpbrk strrchr strtoul])
+
+# check OS
+case "${host}" in
+i[[3456]]86-*-linux*) AC_DEFINE(LINUX_BUILD, 1, [OS is linux]) ac_cv_linux_build="yes" ;;
+sparc*-sun-solaris*) AC_DEFINE(SOLARIS_BUILD, 1, [OS is sparc solaris]) ac_cv_solaris_build="yes";;
+esac
+
+AM_CONDITIONAL(LINUX_BUILD, test "$ac_cv_linux_build" = "yes")
+AM_CONDITIONAL(SOLARIS_BUILD, test "$ac_cv_solaris_build" = "yes")
+
+# Check if we should build libsdp_sys
+AC_CACHE_CHECK(whether to build i386-specific libsdp_sys, ac_cv_libsdp_sys,
+ AC_TRY_COMPILE(,[
+ #if !i386
+ #error Not i386
+ #endif
+ ], ac_cv_libsdp_sys="yes", ac_cv_libsdp_sys="no"))
+
+AM_CONDITIONAL(WANT_LIBSDP_SYS, test "$ac_cv_libsdp_sys" = "yes")
+
+AC_CONFIG_FILES([Makefile src/Makefile libsdp.spec])
+AC_OUTPUT
diff --git a/contrib/ofed/libsdp/libsdp.conf b/contrib/ofed/libsdp/libsdp.conf
new file mode 100644
index 0000000..65f1f83
--- /dev/null
+++ b/contrib/ofed/libsdp/libsdp.conf
@@ -0,0 +1,139 @@
+# libsdp.conf - configuration file for libsdp
+#
+# $Id$
+#
+# Comments are starts with # and cause the entire line after it to be ignored.
+# Any beginning whitespace is skipped. Any line that is empty is also skipped.
+#
+# There are 2 main types of statements supported by this configuration file:
+# - "use" - which defines the address family to be used for the sockets that
+# match the line
+# - "log" - for setting logging related configuration. As the log settings
+# takes immidiate effect we define these at the beggining of the file.
+#
+##############################################################################
+# DEAFUALT SETTINGS:
+# Please do not forget to comment if you want to change these.
+# (the rest of this file explains the syntax and give examples)
+#
+# Get errors printed into the files /tmp/libsdp.log.<uid>/log
+# or /var/log/<path> for root
+log min-level 9 destination file libsdp.log
+#
+# By default we let all servers and client try SDP first.
+# to exclude SDP add "use tcp" rules before these defaults.
+use both server * *:*
+use both client * *:*
+#
+#
+##############################################################################
+#
+# LOG CONFIGURATION:
+# ------------------
+# The log directive allows the user to specify which and where debug and error
+# messages get sent. The log statement format is:
+# log [destination stderr|syslog|file <path>] [min-level <1-9>]
+#
+# destination - defines the destination of the log messages:
+# stderr - messages will be forwarded to the stderr
+# syslog - messages sent to the syslog service
+# file <path> - messages will be written to the file /var/log/<path> for root.
+# for regular user, if full path is requsted <path>.<uid>/log
+# or /tmp/<path>.<uid>/log if no path is requested
+# Due to security reasons, <path> must not be:
+# 1. a soft link
+# 2. owned by other user.
+# 3. Other permissions except User permissions.
+#
+# min-level - defines the verbosity of the log:
+# 9 - only errors are printed
+# 8 - warnings
+# 7 - connect and listen summary (useful for tracking SDP usage)
+# 4 - positive match summary (useful for config file debug)
+# 3 - negative match summary (useful for config file debug)
+# 2 - function calls and return values
+# 1 - debug messages
+#
+# Examples:
+#
+# Get SDP usage per connect and listen into stderr
+# log min-level 7 destination stderr
+#
+# Send errors only into syslog
+# log min-level 9 destination syslog
+#
+##############################################################################
+#
+# SOCKET ADDRESS FAMILY CONTROL:
+# ------------------------------
+# The socket control statements allows the user to specify when libsdp will
+# replace AF_INET/SOCK_STREAM sockets with AF_SDP/SOCK_STREAM
+# sockets. Each control statement specifies a matching rule that all its
+# subexpressions must evaluate as true (logical and) to apply.
+#
+# The statements that control which type of sockets to open are made
+# of the following:
+# use <address-family> <role> <program name> <address|*>:<port range|*>
+#
+# <address-family> can be one of:
+# "sdp" - for specifying when an SDP should be used
+# "tcp" - for specifying when SDP socket should not be matched
+# "both" - for specifying when both SDP and AF_INET sockets should be used.
+#
+# Note: that "both" semantics is different between "server" and "client" roles:
+# For a "server" is means that the server will be listening on both sdp and tcp
+# For a "client" the connect will prefer using sdp but will silently
+# fall back to tcp if the sdp connection failed.
+#
+# <role> can be one of:
+# "server" or "listen" - for defining the listening port address family
+# "client" or "connect" - for defining the connected port address family
+#
+# <program-name|*> field:
+# Defines the program name (not including the path) the rule applies to.
+# Wildcards with same semantics as "ls" are supported (* and ?).
+# So db2* would match on any program with a name starting with db2.
+# t?cp would match on ttcp, etc.
+# If not provided (default) the statement matches all programs.
+#
+# <address|*> means:
+# Either the local address the server is bind to or the remote server
+# address the client connects to. Syntax for address matching is:
+# <IPv4 address>[/<prefix_length>]|*
+# IPv4 address = [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ each sub number < 255
+# prefix_length = [0-9]+ and with value <= 32. A prefix_length of 24
+# matches the subnet mask 255.255.255.0 . A prefix_length of 32
+# requires matching of the exact IP.
+#
+# <port range> is:
+# start-port[-end-port] where port numbers are >0 and < 65536
+#
+# Rules are evaluated in order of definition. So the first match wins.
+# If no match is made libsdp will default to "both".
+#
+# Examples:
+#
+# Use SDP by clients connecting to machines that belongs to subnet 192.168.1.*
+# family role program address:port[-range]
+# use sdp connect * 192.168.1.0/24:*
+#
+# Use SDP by ttcp when it connects to port 5001 of any machine
+# family role program address:port[-range]
+# use sdp listen ttcp *:5001
+#
+# Use TCP for any program with name starting with ttcp* serving ports 22 to 25
+# family role program address:port[-range]
+# use tcp server ttcp* *:22-25
+#
+# Listen on both TCP and SDP by any server that listen on port 8080
+# family role program address:port[-range]
+# use both server * *:8080
+#
+# Connect ssh through SDP and fallback to TCP to hosts on 11.4.8.* port 22
+# family role program address:port[-range]
+# use both connect * 11.4.8.0/24:22
+#
+# NOTE: If all "use" rules are commented SDP will take "simple SDP"
+# mode and use SDP for all connections
+#
+##############################################################################
diff --git a/contrib/ofed/libsdp/libsdp.spec.in b/contrib/ofed/libsdp/libsdp.spec.in
new file mode 100644
index 0000000..c7ba35a
--- /dev/null
+++ b/contrib/ofed/libsdp/libsdp.spec.in
@@ -0,0 +1,55 @@
+
+Summary: LD_PRELOAD-able library for using SDP
+Name: libsdp
+Version: @VERSION@
+Release: 1%{?dist}
+License: GPL/BSD
+Group: System Environment/Libraries
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+Source: http://www.openfabrics.org/downloads/%{name}-%{version}.tar.gz
+Url: http://www.openfabrics.org/
+
+%description
+libsdp can be LD_PRELOAD-ed to have a sockets application use
+InfiniBand Sockets Direct Protocol (SDP) instead of TCP, transparently
+and without recompiling the application.
+
+%package devel
+Summary: Development files for the libsdp
+Group: System Environment/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Development files of libsdp that may be linked directly to an
+application, which may be useful for debugging.
+
+%prep
+%setup -q
+
+%build
+%configure
+make
+
+%install
+make DESTDIR=${RPM_BUILD_ROOT} install
+# remove unpackaged files from the buildroot
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(6644,root,root)
+%{_libdir}/libsdp*.so*
+%defattr(0644,root,root)
+%config(noreplace) %{_sysconfdir}/libsdp.conf
+%config(noreplace) %{_includedir}/linux/sdp_inet.h
+%doc README NEWS ChangeLog COPYING
+
+%files devel
+%defattr(6644,root,root,-)
+%{_libdir}/libsdp*.so
+
+%changelog
+* Sun Jul 22 2007 Vladimir Sokolovsky <vlad@mellanox.co.il>
+- Initial packaging
diff --git a/contrib/ofed/libsdp/src/Makefile.am b/contrib/ofed/libsdp/src/Makefile.am
new file mode 100644
index 0000000..f6907b27
--- /dev/null
+++ b/contrib/ofed/libsdp/src/Makefile.am
@@ -0,0 +1,29 @@
+lib_LTLIBRARIES = libsdp.la $(LIB_SDP_SYS)
+if WANT_LIBSDP_SYS
+LIB_SDP_SYS = libsdp_sys.la
+endif
+
+AM_CFLAGS = -Wall -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libsdp_la_SOURCES = log.c match.c port.c config_parser.c config_scanner.c
+libsdp_la_LDFLAGS = -version-info 1 -ldl -lc
+if SOLARIS_BUILD
+libsdp_la_LDFLAGS += -lsocket
+endif
+libsdp_sys_la_SOURCES = socket.c
+libsdp_sys_la_LDFLAGS = -version-info 1
+
+EXTRA_DIST = libsdp.h linux/sdp_inet.h config_parser.h
+
+config_parser.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/config_parser.y
+ $(YACC) -y -plibsdp_yy -d $(srcdir)/config_parser.y
+ mv y.tab.c config_parser.c
+ mv y.tab.h config_parser.h
+ cp -f config_parser.c config_parser.h $(srcdir)/
+
+config_scanner.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/config_scanner.l
+ $(LEX) -Plibsdp_yy $(srcdir)/config_scanner.l
+ mv lex.libsdp_yy.c config_scanner.c
+ cp -f config_scanner.c $(srcdir)/config_scanner.c
+
+nobase_include_HEADERS = linux/sdp_inet.h
diff --git a/contrib/ofed/libsdp/src/config_parser.c b/contrib/ofed/libsdp/src/config_parser.c
new file mode 100644
index 0000000..87968fc
--- /dev/null
+++ b/contrib/ofed/libsdp/src/config_parser.c
@@ -0,0 +1,1890 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names. */
+#define yyparse libsdp_yyparse
+#define yylex libsdp_yylex
+#define yyerror libsdp_yyerror
+#define yylval libsdp_yylval
+#define yychar libsdp_yychar
+#define yydebug libsdp_yydebug
+#define yynerrs libsdp_yynerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ USE = 258,
+ CLIENT = 259,
+ SERVER = 260,
+ TCP = 261,
+ SDP = 262,
+ BOTH = 263,
+ INT = 264,
+ LOG = 265,
+ DEST = 266,
+ STDERR = 267,
+ SYSLOG = 268,
+ FILENAME = 269,
+ NAME = 270,
+ LEVEL = 271,
+ LINE = 272
+ };
+#endif
+/* Tokens. */
+#define USE 258
+#define CLIENT 259
+#define SERVER 260
+#define TCP 261
+#define SDP 262
+#define BOTH 263
+#define INT 264
+#define LOG 265
+#define DEST 266
+#define STDERR 267
+#define SYSLOG 268
+#define FILENAME 269
+#define NAME 270
+#define LEVEL 271
+#define LINE 272
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 39 "./config_parser.y"
+
+
+/* header section */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "libsdp.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define YYERROR_VERBOSE 1
+
+extern int yyerror(char *msg);
+extern int yylex(void);
+static int parse_err = 0;
+
+struct use_family_rule *__sdp_clients_family_rules_head = NULL;
+struct use_family_rule *__sdp_clients_family_rules_tail = NULL;
+struct use_family_rule *__sdp_servers_family_rules_head = NULL;
+struct use_family_rule *__sdp_servers_family_rules_tail = NULL;
+
+/* some globals to store intermidiate parser state */
+static struct use_family_rule __sdp_rule;
+static int current_role = 0;
+
+int __sdp_config_empty(
+ void
+ )
+{
+ return ( (__sdp_clients_family_rules_head == NULL) &&
+ (__sdp_servers_family_rules_head == NULL) );
+}
+
+/* define the address by 4 integers */
+static void __sdp_set_ipv4_addr(short a0, short a1, short a2, short a3)
+{
+ char buf[16];
+ sprintf(buf,"%d.%d.%d.%d", a0, a1, a2, a3);
+ if (!inet_aton(buf, &( __sdp_rule.ipv4 )))
+ {
+ parse_err = 1;
+ yyerror("provided address is not legal");
+ }
+}
+
+static void __sdp_set_prog_name_expr(char *prog_name_expr)
+{
+ __sdp_rule.prog_name_expr = strdup(prog_name_expr);
+ if (!__sdp_rule.prog_name_expr) {
+ yyerror("fail to allocate program name expression");
+ }
+}
+
+static char *__sdp_get_role_str(int role)
+{
+ if (role == 1) return("server");
+ if (role == 2) return("client");
+ return("unknown role");
+}
+
+extern int __sdp_min_level;
+
+/* dump the current state in readable format */
+static void __sdp_dump_config_state() {
+ char buf[1024];
+ sprintf(buf, "CONFIG: use %s %s %s",
+ __sdp_get_family_str(__sdp_rule.target_family),
+ __sdp_get_role_str( current_role ),
+ __sdp_rule.prog_name_expr);
+ if (__sdp_rule.match_by_addr) {
+ if ( __sdp_rule.prefixlen != 32 )
+ sprintf(buf+strlen(buf), " %s/%d",
+ inet_ntoa( __sdp_rule.ipv4 ), __sdp_rule.prefixlen);
+ else
+ sprintf(buf+strlen(buf), " %s", inet_ntoa( __sdp_rule.ipv4 ));
+ } else {
+ sprintf(buf+strlen(buf), " *");
+ }
+ if (__sdp_rule.match_by_port) {
+ sprintf(buf+strlen(buf), ":%d",__sdp_rule.sport);
+ if (__sdp_rule.eport > __sdp_rule.sport)
+ sprintf(buf+strlen(buf), "-%d",__sdp_rule.eport);
+ }
+ else
+ sprintf(buf+strlen(buf), ":*");
+ sprintf(buf+strlen(buf), "\n");
+ __sdp_log(1, buf);
+}
+
+/* use the above state for making a new rule */
+static void __sdp_add_rule() {
+ struct use_family_rule **p_tail, **p_head, *rule;
+
+ if (__sdp_min_level <= 1) __sdp_dump_config_state();
+ if ( current_role == 1 ) {
+ p_tail = &__sdp_servers_family_rules_tail;
+ p_head = &__sdp_servers_family_rules_head;
+ } else if ( current_role == 2 ) {
+ p_tail = &__sdp_clients_family_rules_tail;
+ p_head = &__sdp_clients_family_rules_head;
+ } else {
+ yyerror("ignoring unknown role");
+ parse_err = 1;
+ return;
+ }
+
+ rule = (struct use_family_rule *)malloc(sizeof(*rule));
+ if (!rule) {
+ yyerror("fail to allocate new rule");
+ parse_err = 1;
+ return;
+ }
+
+ memset(rule, 0, sizeof(*rule));
+ *rule = __sdp_rule;
+ rule->prev = *p_tail;
+ if (!(*p_head)) {
+ *p_head = rule;
+ } else {
+ (*p_tail)->next = rule;
+ } /* if */
+ *p_tail = rule;
+}
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 167 "./config_parser.y"
+{
+ int ival;
+ char *sval;
+}
+/* Line 193 of yacc.c. */
+#line 270 "y.tab.c"
+ YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+#line 192 "./config_parser.y"
+
+ long __sdp_config_line_num;
+
+
+/* Line 216 of yacc.c. */
+#line 286 "y.tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 7
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 36
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 23
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 17
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 33
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 53
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 272
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 19, 2, 2, 22, 21, 20, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 18, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint8 yyprhs[] =
+{
+ 0, 0, 3, 5, 8, 9, 11, 14, 15, 18,
+ 20, 22, 26, 27, 30, 33, 36, 39, 43, 46,
+ 55, 57, 59, 61, 63, 65, 67, 69, 71, 75,
+ 77, 85, 87, 91
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
+{
+ 26, 0, -1, 17, -1, 24, 17, -1, -1, 24,
+ -1, 25, 27, -1, -1, 27, 28, -1, 29, -1,
+ 33, -1, 10, 30, 24, -1, -1, 30, 31, -1,
+ 30, 32, -1, 11, 12, -1, 11, 13, -1, 11,
+ 14, 15, -1, 16, 9, -1, 3, 34, 35, 36,
+ 37, 18, 39, 24, -1, 6, -1, 7, -1, 8,
+ -1, 5, -1, 4, -1, 15, -1, 19, -1, 38,
+ -1, 38, 20, 9, -1, 19, -1, 9, 21, 9,
+ 21, 9, 21, 9, -1, 9, -1, 9, 22, 9,
+ -1, 19, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 198, 198, 199, 201, 202, 205, 208, 209, 213,
+ 214, 218, 221, 222, 223, 227, 228, 229, 233, 237,
+ 241, 242, 243, 247, 248, 252, 253, 257, 258, 259,
+ 263, 267, 268, 269
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "\"use\"", "\"client or connect\"",
+ "\"server or listen\"", "\"tcp\"", "\"sdp\"", "\"both\"",
+ "\"integer value\"", "\"log statement\"", "\"destination\"",
+ "\"stderr\"", "\"syslog\"", "\"file\"", "\"a name\"", "\"min-level\"",
+ "\"new line\"", "':'", "'*'", "'/'", "'.'", "'-'", "$accept", "NL",
+ "ONL", "config", "statements", "statement", "log_statement", "log_opts",
+ "log_dest", "verbosity", "socket_statement", "family", "role", "program",
+ "address", "ipv4", "ports", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 58, 42,
+ 47, 46, 45
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 23, 24, 24, 25, 25, 26, 27, 27, 28,
+ 28, 29, 30, 30, 30, 31, 31, 31, 32, 33,
+ 34, 34, 34, 35, 35, 36, 36, 37, 37, 37,
+ 38, 39, 39, 39
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 2, 0, 1, 2, 0, 2, 1,
+ 1, 3, 0, 2, 2, 2, 2, 3, 2, 8,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 1,
+ 7, 1, 3, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 4, 2, 5, 7, 0, 3, 6, 1, 0, 12,
+ 8, 9, 10, 20, 21, 22, 0, 0, 24, 23,
+ 0, 0, 0, 11, 13, 14, 25, 26, 0, 15,
+ 16, 0, 18, 0, 29, 0, 27, 17, 0, 0,
+ 0, 0, 31, 33, 0, 28, 0, 0, 19, 0,
+ 32, 0, 30
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 2, 3, 4, 6, 10, 11, 17, 24, 25,
+ 12, 16, 20, 28, 35, 36, 44
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -18
+static const yytype_int8 yypact[] =
+{
+ -13, -18, 4, -18, 22, -18, 0, -18, 9, -18,
+ -18, -18, -18, -18, -18, -18, 2, -3, -18, -18,
+ -10, 6, 14, 4, -18, -18, -18, -18, -8, -18,
+ -18, 10, -18, 3, -18, 8, 11, -18, 19, -7,
+ 20, 12, 13, -18, -13, -18, 21, 23, 4, 15,
+ -18, 25, -18
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -18, -17, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, -18, -18, -18, -18
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+ 23, 33, 42, 8, 1, 26, 18, 19, 21, 27,
+ 9, 34, 43, 22, 1, 13, 14, 15, 29, 30,
+ 31, 5, 7, 32, 38, 37, 39, 48, 41, 45,
+ 49, 40, 50, 46, 52, 47, 51
+};
+
+static const yytype_uint8 yycheck[] =
+{
+ 17, 9, 9, 3, 17, 15, 4, 5, 11, 19,
+ 10, 19, 19, 16, 17, 6, 7, 8, 12, 13,
+ 14, 17, 0, 9, 21, 15, 18, 44, 9, 9,
+ 9, 20, 9, 21, 9, 22, 21
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 17, 24, 25, 26, 17, 27, 0, 3, 10,
+ 28, 29, 33, 6, 7, 8, 34, 30, 4, 5,
+ 35, 11, 16, 24, 31, 32, 15, 19, 36, 12,
+ 13, 14, 9, 9, 19, 37, 38, 15, 21, 18,
+ 20, 9, 9, 19, 39, 9, 21, 22, 24, 9,
+ 9, 21, 9
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
+ int yyrule;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ fprintf (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ YYUSE (yyvaluep);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol. */
+int yychar;
+
+/* The semantic value of the look-ahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to look-ahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a look-ahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 15:
+#line 227 "./config_parser.y"
+ { __sdp_log_set_log_stderr(); }
+ break;
+
+ case 16:
+#line 228 "./config_parser.y"
+ { __sdp_log_set_log_syslog(); }
+ break;
+
+ case 17:
+#line 229 "./config_parser.y"
+ { __sdp_log_set_log_file((yyvsp[(3) - (3)].sval)); }
+ break;
+
+ case 18:
+#line 233 "./config_parser.y"
+ { __sdp_log_set_min_level((yyvsp[(2) - (2)].ival)); }
+ break;
+
+ case 19:
+#line 237 "./config_parser.y"
+ { __sdp_add_rule(); }
+ break;
+
+ case 20:
+#line 241 "./config_parser.y"
+ { __sdp_rule.target_family = USE_TCP; }
+ break;
+
+ case 21:
+#line 242 "./config_parser.y"
+ { __sdp_rule.target_family = USE_SDP; }
+ break;
+
+ case 22:
+#line 243 "./config_parser.y"
+ { __sdp_rule.target_family = USE_BOTH; }
+ break;
+
+ case 23:
+#line 247 "./config_parser.y"
+ { current_role = 1; }
+ break;
+
+ case 24:
+#line 248 "./config_parser.y"
+ { current_role = 2; }
+ break;
+
+ case 25:
+#line 252 "./config_parser.y"
+ { __sdp_set_prog_name_expr((yyvsp[(1) - (1)].sval)); }
+ break;
+
+ case 26:
+#line 253 "./config_parser.y"
+ { __sdp_set_prog_name_expr("*"); }
+ break;
+
+ case 27:
+#line 257 "./config_parser.y"
+ { __sdp_rule.match_by_addr = 1; __sdp_rule.prefixlen = 32; }
+ break;
+
+ case 28:
+#line 258 "./config_parser.y"
+ { __sdp_rule.match_by_addr = 1; __sdp_rule.prefixlen = (yyvsp[(3) - (3)].ival); }
+ break;
+
+ case 29:
+#line 259 "./config_parser.y"
+ { __sdp_rule.match_by_addr = 0; __sdp_rule.prefixlen = 32; }
+ break;
+
+ case 30:
+#line 263 "./config_parser.y"
+ { __sdp_set_ipv4_addr((yyvsp[(1) - (7)].ival),(yyvsp[(3) - (7)].ival),(yyvsp[(5) - (7)].ival),(yyvsp[(7) - (7)].ival)); }
+ break;
+
+ case 31:
+#line 267 "./config_parser.y"
+ { __sdp_rule.match_by_port = 1; __sdp_rule.sport= (yyvsp[(1) - (1)].ival); __sdp_rule.eport= (yyvsp[(1) - (1)].ival); }
+ break;
+
+ case 32:
+#line 268 "./config_parser.y"
+ { __sdp_rule.match_by_port = 1; __sdp_rule.sport= (yyvsp[(1) - (3)].ival); __sdp_rule.eport= (yyvsp[(3) - (3)].ival); }
+ break;
+
+ case 33:
+#line 269 "./config_parser.y"
+ { __sdp_rule.match_by_port = 0; __sdp_rule.sport= 0 ; __sdp_rule.eport= 0; }
+ break;
+
+
+/* Line 1267 of yacc.c. */
+#line 1614 "y.tab.c"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse look-ahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse look-ahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+#line 272 "./config_parser.y"
+
+
+int yyerror(char *msg)
+{
+ /* replace the $undefined and $end if exists */
+ char *orig_msg = (char*)malloc(strlen(msg)+25);
+ char *final_msg = (char*)malloc(strlen(msg)+25);
+
+ strcpy(orig_msg, msg);
+
+ char *word = strtok(orig_msg, " ");
+ final_msg[0] = '\0';
+ while (word != NULL) {
+ if (!strncmp(word, "$undefined", 10)) {
+ strcat(final_msg, "unrecognized-token ");
+ } else if (!strncmp(word, "$end",4)) {
+ strcat(final_msg, "end-of-file ");
+ } else {
+ strcat(final_msg, word);
+ strcat(final_msg, " ");
+ }
+ word = strtok(NULL, " ");
+ }
+
+ __sdp_log(9, "Error (line:%ld) : %s\n", __sdp_config_line_num, final_msg);
+ parse_err = 1;
+
+ free(orig_msg);
+ free(final_msg);
+ return 1;
+}
+
+#include <unistd.h>
+#include <errno.h>
+
+/* parse apollo route dump file */
+int __sdp_parse_config (const char *fileName) {
+ extern FILE * libsdp_yyin;
+
+ /* open the file */
+ if (access(fileName, R_OK)) {
+ printf("libsdp Error: No access to open File:%s %s\n",
+ fileName, strerror(errno));
+ return(1);
+ }
+
+ libsdp_yyin = fopen(fileName,"r");
+ if (!libsdp_yyin) {
+ printf("libsdp Error: Fail to open File:%s\n", fileName);
+ return(1);
+ }
+ parse_err = 0;
+ __sdp_config_line_num = 1;
+
+ /* parse it */
+ yyparse();
+
+ fclose(libsdp_yyin);
+ return(parse_err);
+}
+
+
+
diff --git a/contrib/ofed/libsdp/src/config_parser.h b/contrib/ofed/libsdp/src/config_parser.h
new file mode 100644
index 0000000..fd193f3
--- /dev/null
+++ b/contrib/ofed/libsdp/src/config_parser.h
@@ -0,0 +1,95 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ USE = 258,
+ CLIENT = 259,
+ SERVER = 260,
+ TCP = 261,
+ SDP = 262,
+ BOTH = 263,
+ INT = 264,
+ LOG = 265,
+ DEST = 266,
+ STDERR = 267,
+ SYSLOG = 268,
+ FILENAME = 269,
+ NAME = 270,
+ LEVEL = 271,
+ LINE = 272
+ };
+#endif
+/* Tokens. */
+#define USE 258
+#define CLIENT 259
+#define SERVER 260
+#define TCP 261
+#define SDP 262
+#define BOTH 263
+#define INT 264
+#define LOG 265
+#define DEST 266
+#define STDERR 267
+#define SYSLOG 268
+#define FILENAME 269
+#define NAME 270
+#define LEVEL 271
+#define LINE 272
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 167 "./config_parser.y"
+{
+ int ival;
+ char *sval;
+}
+/* Line 1529 of yacc.c. */
+#line 88 "y.tab.h"
+ YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE libsdp_yylval;
+
diff --git a/contrib/ofed/libsdp/src/config_scanner.c b/contrib/ofed/libsdp/src/config_scanner.c
new file mode 100644
index 0000000..661b584
--- /dev/null
+++ b/contrib/ofed/libsdp/src/config_scanner.c
@@ -0,0 +1,1885 @@
+#define yy_create_buffer libsdp_yy_create_buffer
+#define yy_delete_buffer libsdp_yy_delete_buffer
+#define yy_scan_buffer libsdp_yy_scan_buffer
+#define yy_scan_string libsdp_yy_scan_string
+#define yy_scan_bytes libsdp_yy_scan_bytes
+#define yy_flex_debug libsdp_yy_flex_debug
+#define yy_init_buffer libsdp_yy_init_buffer
+#define yy_flush_buffer libsdp_yy_flush_buffer
+#define yy_load_buffer_state libsdp_yy_load_buffer_state
+#define yy_switch_to_buffer libsdp_yy_switch_to_buffer
+#define yyin libsdp_yyin
+#define yyleng libsdp_yyleng
+#define yylex libsdp_yylex
+#define yyout libsdp_yyout
+#define yyrestart libsdp_yyrestart
+#define yytext libsdp_yytext
+#define yywrap libsdp_yywrap
+
+/* A lexical scanner generated by flex*/
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* Some routines like yy_flex_realloc() are emitted as static but are
+ not called by all lexers. This generates warnings in some compilers,
+ notably GCC. Arrange to suppress these. */
+#ifdef __GNUC__
+#define YY_MAY_BE_UNUSED __attribute__((unused))
+#else
+#define YY_MAY_BE_UNUSED
+#endif
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )) YY_MAY_BE_UNUSED;
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 20
+#define YY_END_OF_BUFFER 21
+static yyconst short int yy_accept[171] =
+ { 0,
+ 0, 0, 0, 0, 21, 19, 18, 16, 17, 2,
+ 2, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 18, 1, 15, 15, 2, 2, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 1, 18, 17, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 18, 1, 1, 15, 15, 2, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 1, 0, 0, 0, 0, 0, 0,
+ 3, 0, 11, 0, 0, 0, 10, 9, 1, 15,
+ 15, 15, 15, 15, 15, 3, 15, 11, 15, 15,
+
+ 15, 10, 9, 12, 0, 0, 0, 8, 0, 0,
+ 0, 0, 0, 12, 15, 15, 15, 8, 15, 15,
+ 15, 15, 15, 0, 0, 0, 0, 0, 0, 0,
+ 0, 15, 15, 15, 15, 15, 15, 15, 15, 13,
+ 0, 0, 14, 0, 6, 7, 13, 15, 15, 14,
+ 15, 6, 7, 0, 0, 15, 15, 0, 0, 15,
+ 15, 0, 5, 15, 5, 0, 15, 4, 4, 0
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 1, 4, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 5, 1, 1, 6, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 8, 9, 10, 11,
+
+ 12, 13, 14, 15, 16, 1, 1, 17, 18, 19,
+ 20, 21, 1, 22, 23, 24, 25, 26, 1, 1,
+ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[28] =
+ { 0,
+ 1, 2, 3, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1
+ } ;
+
+static yyconst short int yy_base[177] =
+ { 0,
+ 0, 26, 30, 56, 214, 215, 211, 215, 0, 215,
+ 55, 192, 46, 199, 194, 48, 193, 58, 198, 184,
+ 63, 0, 0, 204, 0, 65, 185, 56, 192, 187,
+ 58, 186, 68, 191, 177, 197, 196, 0, 77, 173,
+ 180, 176, 171, 176, 169, 177, 171, 168, 166, 176,
+ 163, 164, 172, 73, 0, 0, 0, 181, 80, 158,
+ 165, 161, 156, 161, 154, 162, 156, 153, 151, 161,
+ 148, 149, 157, 166, 152, 154, 146, 140, 151, 138,
+ 215, 156, 215, 134, 147, 141, 215, 215, 0, 142,
+ 144, 136, 130, 141, 128, 0, 146, 0, 124, 137,
+
+ 131, 0, 0, 215, 128, 134, 129, 215, 132, 126,
+ 130, 119, 120, 0, 120, 126, 121, 0, 124, 118,
+ 122, 111, 112, 107, 120, 110, 109, 115, 104, 103,
+ 110, 99, 112, 102, 101, 107, 96, 95, 102, 215,
+ 91, 106, 215, 87, 215, 215, 0, 88, 103, 0,
+ 84, 0, 0, 85, 96, 83, 94, 78, 76, 75,
+ 73, 69, 215, 68, 0, 62, 40, 215, 0, 215,
+ 95, 97, 28, 99, 101, 103
+ } ;
+
+static yyconst short int yy_def[177] =
+ { 0,
+ 170, 1, 170, 3, 170, 170, 170, 170, 171, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 172, 173, 174, 173, 173, 173, 173, 173, 173,
+ 173, 173, 173, 173, 173, 175, 170, 171, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 176, 172, 173, 174, 173, 173,
+ 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 173, 173, 175, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 176, 173,
+ 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
+
+ 173, 173, 173, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 173, 173, 173, 173, 173, 173, 173,
+ 173, 173, 173, 170, 170, 170, 170, 170, 170, 170,
+ 170, 173, 173, 173, 173, 173, 173, 173, 173, 170,
+ 170, 170, 170, 170, 170, 170, 173, 173, 173, 173,
+ 173, 173, 173, 170, 170, 173, 173, 170, 170, 173,
+ 173, 170, 170, 173, 173, 170, 173, 170, 173, 0,
+ 170, 170, 170, 170, 170, 170
+ } ;
+
+static yyconst short int yy_nxt[243] =
+ { 0,
+ 6, 7, 8, 9, 6, 10, 11, 6, 12, 13,
+ 14, 6, 15, 6, 6, 6, 16, 17, 6, 6,
+ 6, 6, 18, 19, 20, 6, 6, 21, 57, 22,
+ 23, 7, 8, 24, 23, 25, 26, 23, 27, 28,
+ 29, 23, 30, 23, 23, 23, 31, 32, 23, 23,
+ 23, 23, 33, 34, 35, 23, 23, 21, 169, 36,
+ 39, 39, 41, 45, 54, 42, 55, 46, 48, 49,
+ 59, 59, 61, 65, 54, 62, 55, 66, 68, 69,
+ 168, 50, 39, 39, 51, 59, 59, 167, 166, 165,
+ 164, 70, 163, 162, 71, 38, 38, 56, 56, 58,
+
+ 58, 74, 74, 89, 89, 161, 160, 159, 158, 157,
+ 156, 147, 155, 154, 140, 153, 152, 150, 151, 150,
+ 149, 148, 147, 146, 145, 143, 144, 143, 142, 141,
+ 140, 139, 138, 137, 136, 135, 134, 133, 132, 131,
+ 130, 129, 128, 127, 126, 125, 124, 123, 122, 121,
+ 120, 119, 118, 117, 116, 115, 114, 113, 112, 111,
+ 110, 109, 108, 107, 106, 105, 104, 56, 103, 102,
+ 101, 100, 99, 98, 97, 96, 95, 94, 93, 92,
+ 91, 90, 38, 88, 87, 86, 85, 84, 83, 82,
+ 81, 80, 79, 78, 77, 76, 75, 37, 56, 73,
+
+ 72, 67, 64, 63, 60, 38, 53, 52, 47, 44,
+ 43, 40, 37, 170, 5, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170
+ } ;
+
+static yyconst short int yy_chk[243] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 173, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 4, 167, 4,
+ 11, 11, 13, 16, 21, 13, 21, 16, 18, 18,
+ 26, 26, 28, 31, 54, 28, 54, 31, 33, 33,
+ 166, 18, 39, 39, 18, 59, 59, 164, 162, 161,
+ 160, 33, 159, 158, 33, 171, 171, 172, 172, 174,
+
+ 174, 175, 175, 176, 176, 157, 156, 155, 154, 151,
+ 149, 148, 144, 142, 141, 139, 138, 137, 136, 135,
+ 134, 133, 132, 131, 130, 129, 128, 127, 126, 125,
+ 124, 123, 122, 121, 120, 119, 117, 116, 115, 113,
+ 112, 111, 110, 109, 107, 106, 105, 101, 100, 99,
+ 97, 95, 94, 93, 92, 91, 90, 86, 85, 84,
+ 82, 80, 79, 78, 77, 76, 75, 74, 73, 72,
+ 71, 70, 69, 68, 67, 66, 65, 64, 63, 62,
+ 61, 60, 58, 53, 52, 51, 50, 49, 48, 47,
+ 46, 45, 44, 43, 42, 41, 40, 37, 36, 35,
+
+ 34, 32, 30, 29, 27, 24, 20, 19, 17, 15,
+ 14, 12, 7, 5, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "./config_scanner.l"
+#define INITIAL 0
+/*
+ * Copyright (c) 2006 Mellanox Technologies Ltd. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id: ibnl_scanner.ll,v 1.4 2005/02/23 21:08:37 eitan Exp $
+ */
+#line 36 "./config_scanner.l"
+
+/* #define DEBUG 1 */
+
+#define yyparse libsdp_yyparse
+#define yylex libsdp_yylex
+#define yyerror libsdp_yyerror
+#define yylval libsdp_yylval
+#define yychar libsdp_yychar
+#define yydebug libsdp_yydebug
+#define yynerrs libsdp_yynerrs
+
+#define yywrap libsdp_yywrap
+
+#include <string.h>
+#include <stdio.h>
+#include "config_parser.h"
+extern long __sdp_config_line_num;
+#define CANNAME 1
+
+#line 550 "lex.libsdp_yy.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ yy_current_buffer->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp = NULL, *yy_bp = NULL;
+ register int yy_act;
+
+#line 55 "./config_scanner.l"
+
+
+#line 707 "lex.libsdp_yy.c"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+ yy_current_state += YY_AT_BOL();
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 171 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 215 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 57 "./config_scanner.l"
+{}
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 59 "./config_scanner.l"
+{
+ yylval.ival = atoi(yytext);
+#ifdef DEBUG
+ printf("INT:%d\n",yylval.ival);
+#endif
+ return INT;
+}
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 67 "./config_scanner.l"
+{
+ yylval.ival = LOG;
+#ifdef DEBUG
+ printf("LOG\n");
+#endif
+ return LOG;
+}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 75 "./config_scanner.l"
+{
+ yylval.ival = DEST;
+#ifdef DEBUG
+ printf("DEST\n");
+#endif
+ return DEST;
+}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 83 "./config_scanner.l"
+{
+ yylval.ival = LEVEL;
+#ifdef DEBUG
+ printf("LEVEL\n");
+#endif
+ return LEVEL;
+}
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 91 "./config_scanner.l"
+{
+ yylval.ival = STDERR;
+#ifdef DEBUG
+ printf("STDERR\n");
+#endif
+ return STDERR;
+}
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 99 "./config_scanner.l"
+{
+ yylval.ival = SYSLOG;
+#ifdef DEBUG
+ printf("SYSLOG\n");
+#endif
+ return SYSLOG;
+}
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 107 "./config_scanner.l"
+{
+ yylval.ival = FILENAME;
+#ifdef DEBUG
+ printf("FILENAME\n");
+#endif
+ BEGIN(CANNAME);
+ return FILENAME;
+}
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 116 "./config_scanner.l"
+{
+ yylval.ival = USE;
+#ifdef DEBUG
+ printf("USE\n");
+#endif
+ return USE;
+}
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 124 "./config_scanner.l"
+{
+ yylval.ival = TCP;
+#ifdef DEBUG
+ printf("TCP\n");
+#endif
+ return TCP;
+}
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 132 "./config_scanner.l"
+{
+ yylval.ival = SDP;
+#ifdef DEBUG
+ printf("SDP\n");
+#endif
+ return SDP;
+}
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 140 "./config_scanner.l"
+{
+ yylval.ival = BOTH;
+#ifdef DEBUG
+ printf("BOTH\n");
+#endif
+ return BOTH;
+}
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 148 "./config_scanner.l"
+{
+ yylval.ival = CLIENT;
+#ifdef DEBUG
+ printf("CLIENT\n");
+#endif
+ BEGIN(CANNAME);
+ return CLIENT;
+}
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 157 "./config_scanner.l"
+{
+ yylval.ival = SERVER;
+#ifdef DEBUG
+ printf("SERVER\n");
+#endif
+ BEGIN(CANNAME);
+ return SERVER;
+}
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 166 "./config_scanner.l"
+{
+ yylval.sval = (char *)malloc(strlen(yytext) + 1);
+ strcpy(yylval.sval, yytext);
+#ifdef DEBUG
+ printf("NAME:%s\n",yylval.sval);
+#endif
+ BEGIN(0);
+ return (NAME);
+}
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 176 "./config_scanner.l"
+{
+ __sdp_config_line_num++;
+#ifdef DEBUG
+ printf("LINE\n");
+#endif
+ yylval.ival = LINE;
+ return(LINE);
+}
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 185 "./config_scanner.l"
+{
+ __sdp_config_line_num++;
+}
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 189 "./config_scanner.l"
+{}
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 191 "./config_scanner.l"
+{
+#ifdef DEBUG
+ printf("CHAR:%c\n",yytext[0]);
+#endif
+ return(yytext[0]);
+}
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 198 "./config_scanner.l"
+ECHO;
+ YY_BREAK
+#line 994 "lex.libsdp_yy.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(CANNAME):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+ yy_current_state += YY_AT_BOL();
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 171 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 171 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 170);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+ yy_current_buffer->yy_at_bol = (c == '\n');
+
+ return c;
+ }
+#endif /* YY_NO_INPUT */
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 198 "./config_scanner.l"
+
+
+int yywrap ()
+{
+ return (1);
+}
+
diff --git a/contrib/ofed/libsdp/src/libsdp.h b/contrib/ofed/libsdp/src/libsdp.h
new file mode 100644
index 0000000..0402d55
--- /dev/null
+++ b/contrib/ofed/libsdp/src/libsdp.h
@@ -0,0 +1,131 @@
+/*
+ This software is available to you under a choice of one of two
+ licenses. You may choose to be licensed under the terms of the GNU
+ General Public License (GPL) Version 2, available at
+ <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
+ license, available in the LICENSE.TXT file accompanying this
+ software. These details are also available at
+ <http://openib.org/license.html>.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ Copyright (c) 2004 Topspin Communications. All rights reserved.
+ Copyright (c) 2005-2006 Mellanox Technologies Ltd. All rights reserved.
+
+ $Id$
+*/
+
+#include <netinet/in.h>
+
+/*
+ * SDP specific includes
+ */
+#include "linux/sdp_inet.h"
+
+/* --------------------------------------------------------------------- */
+/* library static and global variables */
+/* --------------------------------------------------------------------- */
+
+/* max string length to store any IPv4/IPv6 address */
+#define MAX_ADDR_STR_LEN 49
+
+typedef enum
+{
+ USE_TCP = 1,
+ USE_SDP,
+ USE_BOTH,
+} use_family_t;
+
+/* some state to string functions */
+static inline char *
+__sdp_get_family_str(
+ use_family_t family )
+{
+ switch ( family ) {
+ case USE_TCP:
+ return "tcp";
+ break;
+ case USE_SDP:
+ return "sdp";
+ break;
+ case USE_BOTH:
+ return "both";
+ break;
+ }
+ return ( "unknown-family" );
+}
+
+/* data structure for holding address family mapoping rules */
+/* note we filter non relevant programs during parsing ... */
+struct use_family_rule
+{
+ struct use_family_rule *prev, *next;
+ int match_by_addr; /* if 0 ignore address match */
+ struct in_addr ipv4; /* IPv4 address for mapping */
+ unsigned char prefixlen; /* length of CIDR prefix (ie /24) */
+ int match_by_port; /* if 0 ignore port match */
+ unsigned short sport, eport; /* start port - end port, inclusive */
+ use_family_t target_family; /* if match - use this family */
+ char *prog_name_expr; /* expression for program name */
+};
+
+extern struct use_family_rule *__sdp_clients_family_rules_head;
+extern struct use_family_rule *__sdp_clients_family_rules_tail;
+extern struct use_family_rule *__sdp_servers_family_rules_head;
+extern struct use_family_rule *__sdp_servers_family_rules_tail;
+
+#define SDP_NETMASK(n) ((n == 0) ? 0 : ~((1UL<<(32 - n)) - 1))
+
+/* match.c */
+use_family_t __sdp_match_connect(
+ const struct sockaddr *sin,
+ const socklen_t addrlen );
+
+use_family_t __sdp_match_listen(
+ const struct sockaddr *sin,
+ const socklen_t addrlen );
+
+/* config.c */
+int __sdp_config_empty(
+ void );
+
+int __sdp_parse_config(
+ const char *config_file );
+
+use_family_t __sdp_match_by_program(
+ );
+
+/* log.c */
+void __sdp_log(
+ int level,
+ char *format,
+ ... );
+
+int __sdp_log_get_level(
+ void );
+
+void __sdp_log_set_min_level(
+ int level );
+
+int __sdp_log_set_log_stderr(
+ void );
+
+int __sdp_log_set_log_syslog(
+ void );
+
+int __sdp_log_set_log_file(
+ char *filename );
+
+/* port.c */
+int __sdp_sockaddr_to_sdp(
+ const struct sockaddr *addr_in,
+ socklen_t addrlen,
+ struct sockaddr_in *addr_out,
+ int *was_ipv6 );
diff --git a/contrib/ofed/libsdp/src/linux/sdp_inet.h b/contrib/ofed/libsdp/src/linux/sdp_inet.h
new file mode 100644
index 0000000..fde347f
--- /dev/null
+++ b/contrib/ofed/libsdp/src/linux/sdp_inet.h
@@ -0,0 +1,52 @@
+/*
+ This software is available to you under a choice of one of two
+ licenses. You may choose to be licensed under the terms of the GNU
+ General Public License (GPL) Version 2, available at
+ <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
+ license, available in the LICENSE.TXT file accompanying this
+ software. These details are also available at
+ <http://openib.org/license.html>.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ Copyright (c) 2004 Topspin Communications. All rights reserved.
+
+ $Id$
+*/
+
+#ifndef _SDP_INET_H
+#define _SDP_INET_H
+
+/*
+ * constants shared between user and kernel space.
+ */
+
+#ifndef SOLARIS_BUILD
+#define AF_INET_SDP 27 /* SDP socket protocol family */
+#define AF_INET6_SDP 28 /* SDP socket protocol family */
+#else
+#define AF_INET_SDP 31 /* This is an invalid family on native solaris
+ * and will only work using QuickTransit */
+//TODO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
+#define AF_INET6_SDP 32 /* SDP socket protocol family */
+#endif
+
+#define AF_INET_STR "AF_INET_SDP" /* SDP enabled environment variable */
+#define AF_INET6_STR "AF_INET6_SDP" /* SDP enabled environment variable */
+
+#ifndef SDP_ZCOPY_THRESH
+#define SDP_ZCOPY_THRESH 80
+#endif
+
+#ifndef SDP_LAST_BIND_ERR
+#define SDP_LAST_BIND_ERR 81
+#endif
+
+#endif /* _SDP_INET_H */
diff --git a/contrib/ofed/libsdp/src/log.c b/contrib/ofed/libsdp/src/log.c
new file mode 100644
index 0000000..c98ee46
--- /dev/null
+++ b/contrib/ofed/libsdp/src/log.c
@@ -0,0 +1,236 @@
+/*
+ This software is available to you under a choice of one of two
+ licenses. You may choose to be licensed under the terms of the GNU
+ General Public License (GPL) Version 2, available at
+ <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
+ license, available in the LICENSE.TXT file accompanying this
+ software. These details are also available at
+ <http://openib.org/license.html>.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ Copyright (c) 2004 Topspin Communications. All rights reserved.
+ Copyright (c) 2006 Mellanox Technologies Ltd. All rights reserved.
+
+ $Id$
+*/
+
+/*
+ * system includes
+ */
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <limits.h>
+
+/*
+ * SDP specific includes
+ */
+#include "libsdp.h"
+
+extern char *program_invocation_short_name;
+
+typedef enum
+{
+ SDP_LOG_FILE,
+ SDP_LOG_SYSLOG,
+} __sdp_log_type_t;
+
+/* --------------------------------------------------------------------- */
+/* library static and global variables */
+/* --------------------------------------------------------------------- */
+int __sdp_min_level = 9;
+static __sdp_log_type_t __sdp_log_type = SDP_LOG_FILE;
+static FILE *__sdp_log_file = NULL;
+
+void
+__sdp_log(
+ int level,
+ char *format,
+ ... )
+{
+ va_list ap;
+ char extra_format[512];
+ time_t timeval;
+ char timestr[32];
+
+ if ( level < __sdp_min_level ) {
+ return;
+ }
+
+ va_start( ap, format );
+ switch ( __sdp_log_type ) {
+ case SDP_LOG_SYSLOG:
+ sprintf( extra_format, "%s[%d] libsdp %s ",
+ program_invocation_short_name, getpid( ), format );
+ vsyslog( LOG_USER | LOG_NOTICE, extra_format, ap );
+ break;
+ case SDP_LOG_FILE:
+ timeval = time(NULL);
+#ifdef SOLARIS_BUILD
+ ctime_r(&timeval, timestr, sizeof timestr);
+#else
+ ctime_r(&timeval, timestr);
+#endif
+ timestr[strlen(timestr)-1] = '\0';
+ sprintf( extra_format, "%s %s[%d] libsdp %s ",
+ timestr, program_invocation_short_name,
+ getpid( ), format );
+ if ( __sdp_log_file == NULL ) {
+ vfprintf( stderr, extra_format, ap );
+#if 0 /* might slow everything too much? */
+ ( void )fflush( stderr );
+#endif
+ } else {
+ vfprintf( __sdp_log_file, extra_format, ap );
+#if 0 /* might slow everything too much? */
+ ( void )fflush( __sdp_log_file );
+#endif
+ }
+ break;
+ }
+ va_end( ap );
+}
+
+int
+__sdp_log_get_level(
+ void )
+{
+ return ( __sdp_min_level );
+}
+
+void
+__sdp_log_set_min_level(
+ int level )
+{
+ __sdp_min_level = level;
+}
+
+static void
+__sdp_log_set_log_type(
+ __sdp_log_type_t type )
+{
+ if ( __sdp_log_file != NULL ) {
+ fclose( __sdp_log_file );
+ __sdp_log_file = NULL;
+ }
+
+ __sdp_log_type = type;
+}
+
+int
+__sdp_log_set_log_stderr(
+ void )
+{
+ __sdp_log_set_log_type( SDP_LOG_FILE );
+ /* NULL means stderr */
+
+ return 1;
+}
+
+int
+__sdp_log_set_log_syslog(
+ void )
+{
+ __sdp_log_set_log_type( SDP_LOG_SYSLOG );
+
+ return 1;
+}
+
+int
+__sdp_log_set_log_file(
+ char *filename )
+{
+ FILE *f;
+ uid_t uid;
+ struct stat lstat_res;
+ int status;
+
+ char *p, tfilename[PATH_MAX + 1];
+
+ /* Strip off any paths from the filename */
+ p = strrchr( filename, '/' );
+
+ /*
+ base on the active user ID we either use /var/log for root or
+ append the uid to the name
+ */
+ uid = geteuid();
+ if (uid == 0) {
+ if ( p )
+ filename = p + 1;
+ snprintf( tfilename, sizeof(tfilename), "/var/log/%s", filename );
+ } else {
+ char tdir[PATH_MAX + 1];
+ /*
+ for regular user, allow log file to be placed in a user
+ requested path. If no path is requested the log file is
+ placed in /tmp/
+ */
+ if ( p )
+ snprintf(tdir, sizeof(tdir), "%s.%d", filename, uid );
+ else
+ snprintf(tdir, sizeof(tdir ), "/tmp/%s.%d", filename, uid );
+
+ if (mkdir(tdir, 0700)) {
+ struct stat stat;
+
+ if (errno != EEXIST) {
+ __sdp_log( 9, "Couldn't create directory '%s' for logging (%m)\n", tdir );
+ return 0;
+ }
+
+ if (lstat(tdir, &stat)) {
+ __sdp_log(9, "Couldn't lstat directory %s\n", tdir);
+ return 0;
+ }
+
+ if (!S_ISDIR(stat.st_mode) || stat.st_uid != uid ||
+ (stat.st_mode & ~(S_IFMT | S_IRWXU))) {
+ __sdp_log( 9, "Cowardly refusing to log into directory:'%s'. "
+ "Make sure it is not: (1) link, (2) other uid, (3) bad permissions."
+ "thus is a security issue.\n", tdir );
+ return 0;
+ }
+ }
+
+ snprintf(tfilename, sizeof(tfilename), "%s/log", tdir);
+ printf("dir: %s file: %s\n", tdir, tfilename);
+ }
+
+ /* double check the file is not a link */
+ status = lstat(tfilename, &lstat_res);
+ if ( (status == 0) && S_ISLNK(lstat_res.st_mode) ) {
+ __sdp_log( 9, "Cowardly refusing to log into:'%s'. "
+ "It is a link - thus is a security issue.\n", tfilename );
+ return 0;
+ }
+
+ f = fopen( tfilename, "a" );
+ if ( !f ) {
+ __sdp_log( 9, "Couldn't open '%s' for logging (%m)\n", tfilename );
+ return 0;
+ }
+
+ __sdp_log_set_log_type( SDP_LOG_FILE );
+ __sdp_log_file = f;
+
+ return 1;
+}
diff --git a/contrib/ofed/libsdp/src/match.c b/contrib/ofed/libsdp/src/match.c
new file mode 100644
index 0000000..fe981b2
--- /dev/null
+++ b/contrib/ofed/libsdp/src/match.c
@@ -0,0 +1,296 @@
+/*
+ This software is available to you under a choice of one of two
+ licenses. You may choose to be licensed under the terms of the GNU
+ General Public License (GPL) Version 2, available at
+ <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
+ license, available in the LICENSE.TXT file accompanying this
+ software. These details are also available at
+ <http://openib.org/license.html>.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ Copyright (c) 2004 Topspin Communications. All rights reserved.
+ Copyright (c) 2005-2006 Mellanox Technologies Ltd. All rights reserved.
+
+ $Id$
+*/
+
+/*
+ * system includes
+ */
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fnmatch.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * SDP specific includes
+ */
+#include "libsdp.h"
+
+/* --------------------------------------------------------------------- */
+/* library static and global variables */
+/* --------------------------------------------------------------------- */
+extern char *program_invocation_name, *program_invocation_short_name;
+
+static void
+get_rule_str(
+ struct use_family_rule *rule,
+ char *buf,
+ size_t len )
+{
+ char addr_buf[MAX_ADDR_STR_LEN];
+ char ports_buf[16];
+ char *target = __sdp_get_family_str( rule->target_family );
+ char *prog = rule->prog_name_expr;
+
+ /* TODO: handle IPv6 in rule */
+ if ( rule->match_by_addr ) {
+ if ( rule->prefixlen != 32 )
+ sprintf( addr_buf, "%s/%d", inet_ntoa( rule->ipv4 ),
+ rule->prefixlen );
+ else
+ sprintf( addr_buf, "%s", inet_ntoa( rule->ipv4 ) );
+ } else {
+ strcpy( addr_buf, "*" );
+ }
+
+ if ( rule->match_by_port )
+ if ( rule->eport > rule->sport )
+ sprintf( ports_buf, "%d", rule->sport );
+ else
+ sprintf( ports_buf, "%d-%d", rule->sport, rule->eport );
+ else
+ sprintf( ports_buf, "*" );
+
+ snprintf( buf, len, "use %s %s %s:%s", target, prog, addr_buf, ports_buf );
+}
+
+/* return 0 if the addresses match */
+static inline int
+match_ipv4_addr(
+ struct use_family_rule *rule,
+ const struct sockaddr_in *sin )
+{
+ return ( rule->ipv4.s_addr !=
+ ( sin->sin_addr.
+ s_addr & htonl( SDP_NETMASK( rule->prefixlen ) ) ) );
+}
+
+static int
+match_ip_addr_and_port(
+ struct use_family_rule *rule,
+ const struct sockaddr *addr_in,
+ const socklen_t addrlen )
+{
+ const struct sockaddr_in *sin = ( const struct sockaddr_in * )addr_in;
+ const struct sockaddr_in6 *sin6 = ( const struct sockaddr_in6 * )addr_in;
+ struct sockaddr_in tmp_sin;
+ unsigned short port;
+ int match = 1;
+ char addr_buf[MAX_ADDR_STR_LEN];
+ const char *addr_str;
+ char rule_str[512];
+
+ if ( __sdp_log_get_level( ) <= 3 ) {
+ if ( sin6->sin6_family == AF_INET6 ) {
+ addr_str =
+ inet_ntop( AF_INET6, ( void * )&( sin6->sin6_addr ), addr_buf,
+ MAX_ADDR_STR_LEN );
+ port = ntohs( sin6->sin6_port );
+ } else {
+ addr_str =
+ inet_ntop( AF_INET, ( void * )&( sin->sin_addr ), addr_buf,
+ MAX_ADDR_STR_LEN );
+ port = ntohs( sin->sin_port );
+ }
+ if ( addr_str == NULL )
+ addr_str = "INVALID_ADDR";
+
+ get_rule_str( rule, rule_str, sizeof( rule_str ) );
+
+ __sdp_log( 3, "MATCH: matching %s:%d to %s => \n", addr_str, port,
+ rule_str );
+ }
+
+ /* We currently only support IPv4 and IPv4 embedded in IPv6 */
+ if ( rule->match_by_port ) {
+ if ( sin6->sin6_family == AF_INET6 )
+ port = ntohs( sin6->sin6_port );
+ else
+ port = ntohs( sin->sin_port );
+
+ if ( ( port < rule->sport ) || ( port > rule->eport ) ) {
+ __sdp_log( 3, "NEGATIVE by port range\n" );
+ match = 0;
+ }
+ }
+
+ if ( match && rule->match_by_addr ) {
+ if ( __sdp_sockaddr_to_sdp( addr_in, addrlen, &tmp_sin, NULL ) ||
+ match_ipv4_addr( rule, &tmp_sin ) ) {
+ __sdp_log( 3, "NEGATIVE by address\n" );
+ match = 0;
+ }
+ }
+
+ if ( match )
+ __sdp_log( 3, "POSITIVE\n" );
+
+ return match;
+}
+
+/* return 1 on match */
+static int
+match_program_name(
+ struct use_family_rule *rule )
+{
+ return !fnmatch( rule->prog_name_expr, program_invocation_short_name, 0 );
+}
+
+static use_family_t
+get_family_by_first_matching_rule(
+ const struct sockaddr *sin,
+ const socklen_t addrlen,
+ struct use_family_rule *rules )
+{
+ struct use_family_rule *rule;
+
+ for ( rule = rules; rule != NULL; rule = rule->next ) {
+ /* skip if not our program */
+ if ( !match_program_name( rule ) )
+ continue;
+
+ /* first rule wins */
+ if ( match_ip_addr_and_port( rule, sin, addrlen ) )
+ return ( rule->target_family );
+ }
+
+ return ( USE_BOTH );
+}
+
+/* return the result of the first matching rule found */
+use_family_t
+__sdp_match_listen(
+ const struct sockaddr * sin,
+ const socklen_t addrlen )
+{
+ use_family_t target_family;
+
+ /* if we do not have any rules we use sdp */
+ if ( __sdp_config_empty( ) )
+ target_family = USE_SDP;
+ else
+ target_family =
+ get_family_by_first_matching_rule( sin, addrlen,
+ __sdp_servers_family_rules_head );
+
+ __sdp_log( 4, "MATCH LISTEN: => %s\n",
+ __sdp_get_family_str( target_family ) );
+
+ return ( target_family );
+}
+
+use_family_t
+__sdp_match_connect(
+ const struct sockaddr * sin,
+ const socklen_t addrlen )
+{
+ use_family_t target_family;
+
+ /* if we do not have any rules we use sdp */
+ if ( __sdp_config_empty( ) )
+ target_family = USE_SDP;
+ else
+ target_family =
+ get_family_by_first_matching_rule( sin, addrlen,
+ __sdp_clients_family_rules_head );
+
+ __sdp_log( 4, "MATCH CONNECT: => %s\n",
+ __sdp_get_family_str( target_family ) );
+
+ return ( target_family );
+}
+
+/* given a set of rules see if there is a global match for current program */
+static use_family_t
+match_by_all_rules_program(
+ struct use_family_rule *rules )
+{
+ int any_sdp = 0;
+ int any_tcp = 0;
+ use_family_t target_family = USE_BOTH;
+ struct use_family_rule *rule;
+
+ for ( rule = rules; ( rule != NULL ) && ( target_family == USE_BOTH );
+ rule = rule->next ) {
+ /* skip if not our program */
+ if ( !match_program_name( rule ) )
+ continue;
+
+ /*
+ * to declare a dont care we either have a dont care address and port
+ * or the previous non global rules use the same target family as the
+ * global rule
+ */
+ if ( rule->match_by_addr || rule->match_by_port ) {
+ /* not a glocal match rule - just track the target family */
+ if ( rule->target_family == USE_SDP )
+ any_sdp++;
+ else if ( rule->target_family == USE_TCP )
+ any_tcp++;
+ } else {
+ /* a global match so we can declare a match by program */
+ if ( ( rule->target_family == USE_SDP ) && ( any_tcp == 0 ) )
+ target_family = USE_SDP;
+ else if ( ( rule->target_family == USE_TCP ) && ( any_sdp == 0 ) )
+ target_family = USE_TCP;
+ }
+ }
+ return ( target_family );
+}
+
+/* return tcp or sdp if the port and role are dont cares */
+use_family_t
+__sdp_match_by_program(
+ )
+{
+ use_family_t server_target_family;
+ use_family_t client_target_family;
+ use_family_t target_family = USE_BOTH;
+
+ if ( __sdp_config_empty( ) ) {
+ target_family = USE_SDP;
+ } else {
+ /* need to try both server and client rules */
+ server_target_family =
+ match_by_all_rules_program( __sdp_servers_family_rules_head );
+ client_target_family =
+ match_by_all_rules_program( __sdp_clients_family_rules_head );
+
+ /* only if both agree */
+ if ( server_target_family == client_target_family )
+ target_family = server_target_family;
+ }
+
+ __sdp_log( 4, "MATCH PROGRAM: => %s\n",
+ __sdp_get_family_str( target_family ) );
+
+ return ( target_family );
+}
diff --git a/contrib/ofed/libsdp/src/port.c b/contrib/ofed/libsdp/src/port.c
new file mode 100644
index 0000000..26bcf7c
--- /dev/null
+++ b/contrib/ofed/libsdp/src/port.c
@@ -0,0 +1,2629 @@
+/*
+ This software is available to you under a choice of one of two
+ licenses. You may choose to be licensed under the terms of the GNU
+ General Public License (GPL) Version 2, available at
+ <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
+ license, available in the LICENSE.TXT file accompanying this
+ software. These details are also available at
+ <http://openib.org/license.html>.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ Copyright (c) 2004 Topspin Communications. All rights reserved.
+ Copyright (c) 2005-2006 Mellanox Technologies Ltd. All rights reserved.
+
+ $Id$
+*/
+
+/*
+ * system includes
+ */
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifdef SOLARIS_BUILD
+/* Our prototypes for ioctl, get*name and accept do not strictly
+ match the headers - we use the following lines to move the header
+ versions 'out of the way' temporarily. */
+#define ioctl __real_ioctl
+#define getsockname __real_getsockname
+#define getpeername __real_getpeername
+#define accept __real_accept
+#define FASYNC 0
+#include <libgen.h>
+#endif
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define __USE_GNU
+#define _GNU_SOURCE /* define RTLD_NEXT */
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdarg.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/poll.h>
+#ifdef __linux__
+#include <sys/epoll.h>
+#endif
+
+#ifdef SOLARIS_BUILD
+/* We're done protecting ourselves from the header prototypes */
+#undef ioctl
+#undef getsockname
+#undef getpeername
+#undef accept
+#endif
+
+/*
+ * SDP specific includes
+ */
+#include "libsdp.h"
+
+/* We can not use sizeof(sockaddr_in6) as the extra scope_id field is not a must have */
+#define IPV6_ADDR_IN_MIN_LEN 24
+
+/* setsockopt() level and optname declarations */
+#define SOL_SDP 1025
+#define SDP_UNBIND 259 /* Unbind socket */
+
+/* Solaris has two entry socket creation functions */
+#define SOCKET_SEMANTIC_DEFAULT 0
+#define SOCKET_SEMANTIC_XNET 1
+
+/* HACK: filter ioctl errors for FIONREAD */
+#define FIONREAD 0x541B
+
+void __attribute__ ((constructor)) __sdp_init(void);
+void __attribute__ ((destructor)) __sdp_fini(void);
+
+/* --------------------------------------------------------------------- */
+/* library type definitions. */
+/* --------------------------------------------------------------------- */
+
+typedef int (*ioctl_func_t) (int fd,
+ int request,
+ void *arg0,
+ void *arg1,
+ void *arg2,
+ void *arg3,
+ void *arg4, void *arg5, void *arg6, void *arg7);
+
+typedef int (*fcntl_func_t) (int fd, int cmd, ...);
+
+typedef int (*socket_func_t) (int domain, int type, int protocol);
+
+typedef int (*setsockopt_func_t) (int s,
+ int level,
+ int optname,
+ const void *optval, socklen_t optlen);
+
+typedef int (*connect_func_t) (int sockfd,
+ const struct sockaddr * serv_addr,
+ socklen_t addrlen);
+
+typedef int (*listen_func_t) (int s, int backlog);
+
+typedef int (*bind_func_t) (int sockfd,
+ const struct sockaddr * my_addr, socklen_t addrlen);
+
+typedef int (*close_func_t) (int fd);
+
+typedef int (*dup_func_t) (int fd);
+
+typedef int (*dup2_func_t) (int oldfd, int newfd);
+
+typedef int (*getsockname_func_t) (int fd,
+ struct sockaddr * name, socklen_t * namelen);
+
+typedef int (*getpeername_func_t) (int fd,
+ struct sockaddr * name, socklen_t * namelen);
+
+typedef int (*accept_func_t) (int fd,
+ struct sockaddr * addr, socklen_t * addrlen);
+
+typedef int (*select_func_t) (int n,
+ fd_set * readfds,
+ fd_set * writefds,
+ fd_set * exceptfds, struct timeval * timeout);
+
+typedef int (*pselect_func_t) (int n,
+ fd_set * readfds,
+ fd_set * writefds,
+ fd_set * exceptfds,
+ const struct timespec * timeout,
+ const sigset_t * sigmask);
+
+typedef int (*poll_func_t) (struct pollfd * ufds,
+ unsigned long int nfds, int timeout);
+
+#ifdef __linux__
+typedef int (*epoll_create_func_t) (int size);
+
+typedef int (*epoll_ctl_func_t) (int epfd,
+ int op, int fd, struct epoll_event * event);
+
+typedef int (*epoll_wait_func_t) (int epfd,
+ struct epoll_event * events,
+ int maxevents, int timeout);
+
+typedef int (*epoll_pwait_func_t) (int epfd,
+ struct epoll_event * events,
+ int maxevents,
+ int timeout, const sigset_t * sigmask);
+#endif
+
+
+struct socket_lib_funcs {
+ ioctl_func_t ioctl;
+ fcntl_func_t fcntl;
+ socket_func_t socket;
+ setsockopt_func_t setsockopt;
+ connect_func_t connect;
+ listen_func_t listen;
+ bind_func_t bind;
+ close_func_t close;
+ dup_func_t dup;
+ dup2_func_t dup2;
+ getpeername_func_t getpeername;
+ getsockname_func_t getsockname;
+ accept_func_t accept;
+ select_func_t select;
+ pselect_func_t pselect;
+ poll_func_t poll;
+#ifdef __linux__
+ epoll_create_func_t epoll_create;
+ epoll_ctl_func_t epoll_ctl;
+ epoll_wait_func_t epoll_wait;
+ epoll_pwait_func_t epoll_pwait;
+#endif
+}; /* socket_lib_funcs */
+
+#ifdef SOLARIS_BUILD
+/* Solaris has another interface to socket functions prefixed with __xnet_ */
+struct socket_lib_xnet_funcs {
+ socket_func_t socket;
+ connect_func_t connect;
+ listen_func_t listen;
+ bind_func_t bind;
+};
+#endif
+
+static int simple_sdp_library;
+static int max_file_descriptors;
+static int dev_null_fd;
+volatile static int init_status = 0; /* 0: idle, 1:during, 2:ready */
+
+/* --------------------------------------------------------------------- */
+/* library static and global variables */
+/* --------------------------------------------------------------------- */
+
+/* glibc provides these symbols - for Solaris builds we fake them
+ * until _init is called, at which point we quiz libdl.. */
+#ifdef SOLARIS_BUILD
+char *program_invocation_name = "[progname]", *program_invocation_short_name =
+ "[short_progname]";
+#else
+extern char *program_invocation_name, *program_invocation_short_name;
+#endif
+
+#ifdef RTLD_NEXT
+static void *__libc_dl_handle = RTLD_NEXT;
+#else
+static void *__libc_dl_handle;
+#endif
+
+/* extra fd attributes we need for our algorithms */
+struct sdp_extra_fd_attributes {
+ int shadow_fd; /* file descriptor of shadow sdp socket */
+ short last_accept_was_tcp; /* used by accept to alternate tcp and sdp */
+ short is_sdp; /* 1 if the fd represents an sdp socket */
+}; /* sdp_extra_fd_attributes */
+
+/* stores the extra attributes struct by fd */
+static struct sdp_extra_fd_attributes *libsdp_fd_attributes;
+
+static struct socket_lib_funcs _socket_funcs = {
+ .socket = NULL,
+ /* Automatically sets all other elements to NULL */
+}; /* _socket_funcs */
+
+#ifdef SOLARIS_BUILD
+static struct socket_lib_xnet_funcs _socket_xnet_funcs = {
+ .socket = NULL,
+ /* Automatically sets all other elements to NULL */
+};
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Prototypes */
+/* --------------------------------------------------------------------- */
+void __sdp_init(void);
+
+/* --------------------------------------------------------------------- */
+/* */
+/* local static functions. */
+/* */
+/* --------------------------------------------------------------------- */
+
+/* ========================================================================= */
+/*..init_extra_attribute -- initialize the set of extra attributes for a fd */
+static void init_extra_attribute(int fd)
+{
+ if ((0 <= fd) && (max_file_descriptors > fd)) {
+ libsdp_fd_attributes[fd].shadow_fd = -1;
+ libsdp_fd_attributes[fd].is_sdp = 0;
+ libsdp_fd_attributes[fd].last_accept_was_tcp = -1;
+ }
+}
+
+static inline int is_valid_fd(int fd)
+{
+ return (0 <= fd) && (fd < max_file_descriptors);
+}
+
+/* ========================================================================= */
+/*..get_shadow_fd_by_fd -- given an fd return its shadow fd if exists */
+static inline int get_shadow_fd_by_fd(int fd)
+{
+ if (is_valid_fd(fd))
+ return libsdp_fd_attributes[fd].shadow_fd;
+ else
+ return -1;
+}
+
+/* ========================================================================= */
+/*..set_shadow_for_fd -- */
+static inline void set_shadow_for_fd(int fd, int shadow_fd)
+{
+ if (is_valid_fd(fd))
+ libsdp_fd_attributes[fd].shadow_fd = shadow_fd;
+}
+
+/* ========================================================================= */
+/*..set_is_sdp_socket -- */
+static inline void set_is_sdp_socket(int fd, short is_sdp)
+{
+ if (is_valid_fd(fd))
+ libsdp_fd_attributes[fd].is_sdp = is_sdp;
+}
+
+/* ========================================================================= */
+/*..get_is_sdp_socket -- given an fd return 1 if it is an SDP socket */
+static inline int get_is_sdp_socket(int fd)
+{
+ if (is_valid_fd(fd))
+ return libsdp_fd_attributes[fd].is_sdp;
+ else
+ return 0;
+}
+
+/* ========================================================================= */
+/*..last_accept_was_tcp -- given an fd return 1 if last accept was tcp */
+static inline int last_accept_was_tcp(int fd)
+{
+ if (is_valid_fd(fd))
+ return libsdp_fd_attributes[fd].last_accept_was_tcp;
+ else
+ return 0;
+}
+
+/* ========================================================================= */
+/*..set_last_accept -- given an fd set last accept was tcp */
+static inline void set_last_accept(int fd, int was_tcp)
+{
+ if (is_valid_fd(fd))
+ libsdp_fd_attributes[fd].last_accept_was_tcp = was_tcp;
+}
+
+/* ========================================================================= */
+/*..cleanup_shadow -- an error occured on an SDP socket, cleanup */
+static int cleanup_shadow(int fd)
+{
+ int shadow_fd = get_shadow_fd_by_fd(fd);
+
+ if (shadow_fd == -1)
+ return 0;
+ libsdp_fd_attributes[fd].shadow_fd = -1;
+ libsdp_fd_attributes[fd].last_accept_was_tcp = 0;
+ return (_socket_funcs.close(shadow_fd));
+} /* cleanup_shadow */
+
+/* ========================================================================= */
+/*..replace_fd_with_its_shadow -- perform all required for such promotion */
+static int replace_fd_with_its_shadow(int fd)
+{
+ int shadow_fd = libsdp_fd_attributes[fd].shadow_fd;
+
+ if (shadow_fd == -1) {
+ __sdp_log(9, "Error replace_fd_with_its_shadow: no shadow for fd:%d\n",
+ fd);
+ return EINVAL;
+ }
+
+ /* copy the attributes of the shadow before we clean them up */
+ libsdp_fd_attributes[fd] = libsdp_fd_attributes[shadow_fd];
+ libsdp_fd_attributes[fd].shadow_fd = -1;
+ if (_socket_funcs.dup2(shadow_fd, fd) < 0) {
+ init_extra_attribute(fd);
+ _socket_funcs.close(shadow_fd);
+ return EINVAL;
+ }
+ _socket_funcs.close(shadow_fd);
+ return 0;
+}
+
+static sa_family_t get_sdp_domain(int domain)
+{
+ if (AF_INET_SDP == domain || AF_INET6_SDP == domain)
+ return domain;
+
+ if (AF_INET == domain)
+ return AF_INET_SDP;
+ else if (AF_INET6 == domain)
+ return AF_INET6_SDP;
+
+ __sdp_log(9, "Error %s: unknown TCP domain: %d\n", __func__, domain);
+
+ return -1;
+}
+
+static int get_sock_domain(int sd)
+{
+ struct sockaddr_storage tmp_sin;
+ socklen_t tmp_sinlen = sizeof(tmp_sin);
+
+ if (_socket_funcs.getsockname(sd, (struct sockaddr *) &tmp_sin, &tmp_sinlen) < 0) {
+ __sdp_log(9, "Error %s: getsockname return <%d> for socket\n", __func__, errno);
+ return -1;
+ }
+
+ return ((struct sockaddr *)&tmp_sin)->sa_family;
+}
+
+/* ========================================================================= */
+/*..is_filtered_unsuported_sockopt -- return 1 if to filter sockopt failure */
+static inline int is_filtered_unsuported_sockopt(int level, int optname)
+{
+ /*
+ * TODO: until we know exactly which unsupported opts are really
+ * a don't care we always pass the error
+ */
+ return 0;
+#if 0
+ /* these are the SOL_TCP OPTS we should consider filterring */
+ TCP_NODELAY 1 /* Don't delay send to coalesce packets */
+ TCP_MAXSEG 2 /* Set maximum segment size */
+ TCP_CORK 3 /* Control sending of partial frames */
+ TCP_KEEPIDLE 4 /* Start keeplives after this period */
+ TCP_KEEPINTVL 5 /* Interval between keepalives */
+ TCP_KEEPCNT 6 /* Number of keepalives before death */
+ TCP_SYNCNT 7 /* Number of SYN retransmits */
+ TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
+ TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
+ TCP_WINDOW_CLAMP 10 /* Bound advertised window */
+ TCP_INFO 11 /* Information about this connection. */
+ TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */
+#endif
+}
+
+/* ========================================================================= */
+/*..is_invalid_addr -- return 1 if given pointer is not valid */
+/* NOTE: invalidation of the size is going to happen during actual call */
+static inline int is_invalid_addr(const void *p)
+{
+ /* HACK: on some systems we can not write to check for pointer validity */
+ size_t ret = fcntl(dev_null_fd, F_GETLK, p);
+
+ ret = (errno == EFAULT);
+ errno = 0;
+ return ret;
+}
+
+/* ========================================================================= */
+/*..get_addr_str -- fill in the given buffer with addr str or return 1 */
+static int get_addr_str(const struct sockaddr *addr, char *buf, size_t len)
+{
+ const struct sockaddr_in *sin = (struct sockaddr_in *) addr;
+ const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr;
+ char const *conv_res;
+
+ if (sin->sin_family == AF_INET) {
+ conv_res = inet_ntop(AF_INET, (void *) &(sin->sin_addr), buf, len);
+ } else if (sin6->sin6_family == AF_INET6) {
+ conv_res = inet_ntop(AF_INET6, (void *) &sin6->sin6_addr, buf, len);
+ } else {
+ strncpy(buf, "unknown address family", len);
+ conv_res = (char *) 1;
+ }
+ return conv_res == NULL;
+}
+
+/* --------------------------------------------------------------------- */
+/* */
+/* Socket library function overrides. */
+/* */
+/* --------------------------------------------------------------------- */
+
+/* ========================================================================= */
+/*..ioctl -- replacement ioctl call. */
+int
+ioctl(int fd,
+ int request,
+ void *arg0,
+ void *arg1,
+ void *arg2, void *arg3, void *arg4, void *arg5, void *arg6, void *arg7)
+{
+ int shadow_fd;
+ int sret = 0;
+ int ret = 0;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.ioctl) {
+ __sdp_log(9, "Error ioctl: no implementation for ioctl found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+
+ __sdp_log(2, "IOCTL: <%s:%d:%d> request <%d>\n",
+ program_invocation_short_name, fd, shadow_fd, request);
+
+ ret = _socket_funcs.ioctl(fd, request,
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+
+ /* HACK: avoid failing on FIONREAD error as SDP does not support it at the moment */
+ if ((ret < 0) && get_is_sdp_socket(fd) && (request == FIONREAD)) {
+ __sdp_log(8, "Warning ioctl: "
+ "Ignoring FIONREAD error for SDP socket.\n");
+ ret = 0;
+ }
+
+ /* if shadow and no error on tcp */
+ if ((ret >= 0) && (-1 != shadow_fd)) {
+ sret = _socket_funcs.ioctl(shadow_fd, request,
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6,
+ arg7);
+ /* HACK: avoid failing on FIONREAD error as SDP does not support it at the moment */
+ if ((sret < 0) && (request == FIONREAD)) {
+ __sdp_log(8, "Warning ioctl: "
+ "Ignoring FIONREAD error for shadow SDP socket.\n");
+ sret = 0;
+ }
+
+ if (sret < 0) {
+ __sdp_log(9, "Error ioctl: "
+ "<%d> calling ioctl for SDP socket, closing it.\n",
+ errno);
+ cleanup_shadow(fd);
+ }
+ }
+
+ __sdp_log(2, "IOCTL: <%s:%d:%d> result <%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd, ret, sret);
+
+ return ret;
+} /* ioctl */
+
+/* ========================================================================= */
+/*..fcntl -- replacement fcntl call. */
+int fcntl(int fd, int cmd, ...)
+{
+ int shadow_fd;
+ int sret = 0;
+ int ret = 0;
+
+ void *arg;
+ va_list ap;
+
+ va_start(ap, cmd);
+ arg = va_arg(ap, void *);
+ va_end(ap);
+
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.fcntl) {
+ __sdp_log(9, "Error fcntl: no implementation for fcntl found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+
+ __sdp_log(2, "FCNTL: <%s:%d:%d> command <%d> argument <%p>\n",
+ program_invocation_short_name, fd, shadow_fd, cmd, arg);
+
+ ret = _socket_funcs.fcntl(fd, cmd, arg);
+ if ((ret >= 0) && (-1 != shadow_fd)) {
+ sret = _socket_funcs.fcntl(shadow_fd, cmd, arg);
+ if (sret < 0) {
+ __sdp_log(9, "Error fcntl:"
+ " <%d> calling fcntl(%d, %d, %p) for SDP socket. Closing it.\n",
+ shadow_fd, cmd, arg, errno);
+ cleanup_shadow(fd);
+ }
+ }
+
+ __sdp_log(2, "FCNTL: <%s:%d:%d> result <%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd, ret, sret);
+
+ return ret;
+} /* fcntl */
+
+/* ========================================================================= */
+/*..setsockopt -- replacement setsockopt call. */
+int
+setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+ int shadow_fd;
+ int sret = 0;
+ int ret = 0;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.setsockopt) {
+ __sdp_log(9, "Error setsockopt:"
+ " no implementation for setsockopt found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+
+ __sdp_log(2, "SETSOCKOPT: <%s:%d:%d> level <%d> name <%d>\n",
+ program_invocation_short_name, fd, shadow_fd, level, optname);
+
+ if (level == SOL_SOCKET && optname == SO_KEEPALIVE && get_is_sdp_socket(fd)) {
+ level = AF_INET_SDP;
+ __sdp_log(2, "SETSOCKOPT: <%s:%d:%d> substitute level %d\n",
+ program_invocation_short_name, fd, shadow_fd, level);
+ }
+
+ ret = _socket_funcs.setsockopt(fd, level, optname, optval, optlen);
+ if ((ret >= 0) && (shadow_fd != -1)) {
+ if (level == SOL_SOCKET && optname == SO_KEEPALIVE &&
+ get_is_sdp_socket(shadow_fd)) {
+ level = AF_INET_SDP;
+ __sdp_log(2, "SETSOCKOPT: <%s:%d:%d> substitute level %d\n",
+ program_invocation_short_name, fd, shadow_fd, level);
+ }
+
+ sret = _socket_funcs.setsockopt(shadow_fd, level, optname, optval, optlen);
+ if (sret < 0) {
+ __sdp_log(8, "Warning sockopts:"
+ " ignoring error on shadow SDP socket fd:<%d>\n", fd);
+ /*
+ * HACK: we should allow some errors as some sock opts are unsupported
+ * __sdp_log(9, "Error %d calling setsockopt for SDP socket, closing\n", errno);
+ * cleanup_shadow(fd);
+ */
+ }
+ }
+
+ /* Due to SDP limited implmentation of sockopts we ignore some errors */
+ if ((ret < 0) && get_is_sdp_socket(fd) &&
+ is_filtered_unsuported_sockopt(level, optname)) {
+ __sdp_log(8, "Warning sockopts: "
+ "ignoring error on non implemented sockopt on SDP socket"
+ " fd:<%d> level:<%d> opt:<%d>\n", fd, level, optval);
+ ret = 0;
+ }
+
+ __sdp_log(2, "SETSOCKOPT: <%s:%d:%d> result <%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd, ret, sret);
+
+ return ret;
+} /* setsockopt */
+
+/* ========================================================================= */
+/*..socket -- replacement socket call. */
+
+static inline int __create_socket_semantic(int domain,
+ int type,
+ int protocol, int semantics)
+{
+ return
+#ifdef SOLARIS_BUILD
+ (semantics == SOCKET_SEMANTIC_XNET) ?
+ _socket_xnet_funcs.socket(domain, type, protocol) :
+#endif
+ _socket_funcs.socket(domain, type, protocol);
+}
+
+/* Contains the main logic for creating shadow SDP sockets */
+static int __create_socket(int domain, int type, int protocol, int semantics)
+{
+ int s = -1;
+ int shadow_fd = -1;
+ use_family_t family_by_prog;
+ int sdp_domain;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.socket) {
+ __sdp_log(9, "Error socket: no implementation for socket found\n");
+ return -1;
+ }
+
+ __sdp_log(2, "SOCKET: <%s> domain <%d> type <%d> protocol <%d>\n",
+ program_invocation_short_name, domain, type, protocol);
+
+ sdp_domain = get_sdp_domain(domain);
+ if (sdp_domain < 0) {
+ errno = EAFNOSUPPORT;
+ s = -1;
+ goto done;
+ }
+
+ /* check to see if we can skip the shadow */
+ if ((AF_INET == domain || AF_INET6 == domain) && (SOCK_STREAM == type))
+ if (simple_sdp_library)
+ family_by_prog = USE_SDP;
+ else
+ family_by_prog = __sdp_match_by_program();
+ else if (AF_INET_SDP == domain || AF_INET6_SDP == domain)
+ family_by_prog = USE_SDP;
+ else
+ family_by_prog = USE_TCP;
+
+ if (family_by_prog == USE_TCP) {
+ __sdp_log(1, "SOCKET: making TCP only socket (no shadow)\n");
+ s = __create_socket_semantic(domain, type, protocol, semantics);
+ init_extra_attribute(s);
+ set_is_sdp_socket(s, 0);
+ goto done;
+ }
+
+ if (family_by_prog == USE_SDP) {
+ /* HACK: convert the protocol if IPPROTO_IP */
+ if (protocol == 0)
+ protocol = IPPROTO_TCP;
+
+ __sdp_log(1, "SOCKET: making SDP socket type:%d proto:%d\n",
+ type, protocol);
+ s = __create_socket_semantic(sdp_domain, type, protocol, semantics);
+ init_extra_attribute(s);
+ set_is_sdp_socket(s, 1);
+ goto done;
+ }
+
+ /* HACK: if we fail creating the TCP socket should we abort ? */
+ __sdp_log(1, "SOCKET: making TCP socket\n");
+ s = __create_socket_semantic(domain, type, protocol, semantics);
+ init_extra_attribute(s);
+ set_is_sdp_socket(s, 0);
+ if (is_valid_fd(s)) {
+ if (((AF_INET == domain) || (AF_INET6 == domain)) &&
+ (SOCK_STREAM == type)) {
+
+ if (protocol == 0)
+ protocol = IPPROTO_TCP;
+ __sdp_log(1, "SOCKET: making SDP shadow socket type:%d proto:%d\n",
+ type, protocol);
+ shadow_fd =
+ __create_socket_semantic(sdp_domain, type, protocol,
+ semantics);
+ if (is_valid_fd(shadow_fd)) {
+ init_extra_attribute(shadow_fd);
+ if (libsdp_fd_attributes[s].shadow_fd != -1) {
+ __sdp_log(8, "Warning socket: "
+ "overriding existing shadow fd:%d for fd:%d\n",
+ libsdp_fd_attributes[s].shadow_fd, s);
+ }
+ set_is_sdp_socket(shadow_fd, 1);
+ set_shadow_for_fd(s, shadow_fd);
+ } else {
+ __sdp_log(9,
+ "Error socket: <%d> calling socket for SDP socket\n",
+ errno);
+ /* fail if we did not make the SDP socket */
+ __sdp_log(1, "SOCKET: closing TCP socket:<%d>\n", s);
+ _socket_funcs.close(s);
+ s = -1;
+ }
+ }
+ } else {
+ __sdp_log(9, "Error socket: "
+ "ignoring SDP socket since TCP fd:%d out of range\n", s);
+ }
+
+done:
+ __sdp_log(2, "SOCKET: <%s:%d:%d>\n",
+ program_invocation_short_name, s, shadow_fd);
+
+ return s;
+} /* socket */
+
+int socket(int domain, int type, int protocol)
+{
+ return __create_socket(domain, type, protocol, SOCKET_SEMANTIC_DEFAULT);
+}
+
+#ifdef SOLARIS_BUILD
+int __xnet_socket(int domain, int type, int protocol)
+{
+ return __create_socket(domain, type, protocol, SOCKET_SEMANTIC_XNET);
+}
+#endif
+
+/* ========================================================================= */
+/*..get_fd_addr_port_num - obtain the port the fd is attached to */
+static int get_fd_addr_port_num(int sd)
+{
+ struct sockaddr_storage addr;
+ int ret;
+ const struct sockaddr_in *sin;
+ socklen_t addrlen = sizeof(addr);
+
+ ret = _socket_funcs.getsockname(sd, (struct sockaddr *) &addr, &addrlen);
+
+ if (ret) {
+ __sdp_log(9, "Error: in get_fd_addr_port_num - Failed to get getsockname\n");
+ return -1;
+ }
+
+ /* port num is in same location for IPv4 and IPv6 */
+ sin = (const struct sockaddr_in *) &addr;
+ return ntohs(sin->sin_port);
+}
+
+/* ========================================================================= */
+/*..set_addr_port_num - sets the port in the given address */
+static int set_addr_port_num(const struct sockaddr *addr, int port)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *) addr;
+
+ /* port num is in same location for IPv4 and IPv6 */
+ sin->sin_port = htons(port);
+ return 0;
+}
+
+/* ========================================================================= */
+/* perform a bind with the given socket semantics */
+static inline int
+__bind_semantics(int fd,
+ const struct sockaddr *my_addr,
+ socklen_t addrlen, int semantics)
+{
+ return
+#ifdef SOLARIS_BUILD
+ (semantics == SOCKET_SEMANTIC_XNET) ?
+ _socket_xnet_funcs.bind(fd, my_addr, addrlen) :
+#endif
+ _socket_funcs.bind(fd, my_addr, addrlen);
+}
+
+/* ========================================================================= */
+/*..find_free_port - find same free port on both TCP and SDP */
+#define MAX_BIND_ANY_PORT_TRIES 20000
+static int
+find_free_port(const struct sockaddr *sin_addr,
+ const socklen_t addrlen,
+ int orig_sd,
+ int *sdp_sd, int *tcp_sd, int semantics)
+{
+ static int tcp_turn = 1;
+ int tmp_turn = tcp_turn;
+ int num_of_loops = 0;
+ int port = -1;
+ int tmp_sd[2];
+ unsigned int yes = 1;
+ int ret;
+ int domain, sdp_domain;
+
+ __sdp_log(2, "find_free_port: starting search for common free port\n");
+
+ /* need to obtain the address family from the fd */
+ domain = get_sock_domain(orig_sd);
+ if (domain == -1) {
+ errno = EFAULT;
+ goto done;
+ }
+
+ sdp_domain = get_sdp_domain(domain);
+ if (sdp_domain < 0) {
+ errno = EFAULT;
+ goto done;
+ }
+
+ do {
+ __sdp_log(1, "find_free_port: taking loop (%d)\n", ++num_of_loops);
+
+ __sdp_log(1, "find_free_port: creating the two sockets\n");
+ tmp_sd[0] = _socket_funcs.socket(sdp_domain, SOCK_STREAM, IPPROTO_TCP);
+ if (tmp_sd[0] < 0) {
+ __sdp_log(8, "Warning find_free_port: creating first socket failed\n");
+ goto done;
+ }
+
+ _socket_funcs.setsockopt(tmp_sd[0], SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
+
+ tmp_sd[1] = _socket_funcs.socket(domain, SOCK_STREAM, IPPROTO_TCP);
+ if (tmp_sd[1] < 0) {
+ __sdp_log(8, "Warning find_free_port: creating second socket failed\n");
+ _socket_funcs.close(tmp_sd[0]);
+ goto done;
+ }
+
+ _socket_funcs.setsockopt(tmp_sd[1], SOL_SOCKET, SO_REUSEADDR, &yes,
+ sizeof(yes));
+
+ __sdp_log(1, "find_free_port: binding first %s socket\n",
+ tmp_turn ? "tcp" : "sdp");
+ ret = __bind_semantics(tmp_sd[tmp_turn], sin_addr, addrlen, semantics);
+ if (ret < 0) {
+ __sdp_log(8,
+ "Warning find_free_port: binding first socket failed:%s\n",
+ strerror(errno));
+ _socket_funcs.close(tmp_sd[0]);
+ _socket_funcs.close(tmp_sd[1]);
+ goto done;
+ }
+
+ __sdp_log(1, "find_free_port: listening on first socket\n");
+ ret = _socket_funcs.listen(tmp_sd[tmp_turn], 5);
+ if (ret < 0) {
+ __sdp_log(8, "Warning find_free_port: listening on first socket failed:%s\n",
+ strerror(errno));
+ _socket_funcs.close(tmp_sd[0]);
+ _socket_funcs.close(tmp_sd[1]);
+ goto done;
+ }
+
+ port = get_fd_addr_port_num(tmp_sd[tmp_turn]);
+ if (port < 0) {
+ __sdp_log(8, "Warning find_free_port: first socket port:%d < 0\n",
+ port);
+ _socket_funcs.close(tmp_sd[0]);
+ _socket_funcs.close(tmp_sd[1]);
+ goto done;
+ }
+ __sdp_log(1, "find_free_port: first socket port:%u\n", port);
+
+ set_addr_port_num(sin_addr, port);
+
+ __sdp_log(1, "find_free_port: binding second socket\n");
+ ret = __bind_semantics(tmp_sd[1 - tmp_turn], sin_addr, addrlen, semantics);
+ if (ret < 0) {
+ /* bind() for sdp socket failed. It is acceptable only
+ * if the IP is not part of IB network. */
+
+ if (errno != EADDRINUSE) {
+ __sdp_log(8, "Warning find_free_port: "
+ "binding second socket failed with %s\n",
+ strerror(errno));
+ goto close_and_mark;
+ } else {
+ int err;
+#ifdef __linux__
+ socklen_t len = sizeof(int);
+
+ ret = getsockopt(tmp_sd[1 - tmp_turn], SOL_TCP,
+ SDP_LAST_BIND_ERR, &err, &len);
+ if (-1 == ret) {
+ __sdp_log(9, "Error %s:getsockopt: %s\n",
+ __func__, strerror(errno));
+ goto close_and_mark;
+ }
+#else
+ err = -errno;
+#endif
+ if (-ENOENT == err || -EADDRINUSE != err) {
+ /* bind() failed due to either:
+ * 1. IP is ETH, not IB, so can't bind() to sdp socket.
+ * 2. real error.
+ * Continue only with TCP */
+ goto close_and_mark;
+ }
+ __sdp_log(1, "find_free_port: %s port %u was busy\n",
+ 1 - tmp_turn ? "tcp" : "sdp",
+ ntohs(((const struct sockaddr_in *)sin_addr)->sin_port));
+ }
+
+ /* close the sockets - we will need new ones ... */
+ __sdp_log(1,
+ "find_free_port: closing the two sockets before next loop\n");
+ _socket_funcs.close(tmp_sd[0]);
+ _socket_funcs.close(tmp_sd[1]);
+
+ port = -1;
+ /* we always start with tcp so we keep the original setting for now */
+ /* tmp_turn = 1 - tmp_turn; */
+ }
+
+ } while ((port < 0) && (num_of_loops < MAX_BIND_ANY_PORT_TRIES));
+
+setfds:
+ tcp_turn = tmp_turn;
+ *sdp_sd = tmp_sd[0];
+ *tcp_sd = tmp_sd[1];
+
+done:
+ __sdp_log(2, "find_free_port: return port:<%d>\n", port);
+ return port;
+
+close_and_mark:
+ _socket_funcs.close(tmp_sd[0]);
+ tmp_sd[0] = -1; /* mark with error */
+ goto setfds;
+
+}
+
+/* ========================================================================= */
+/*..check_legal_bind - check if given address is okay for both TCP and SDP */
+static int
+check_legal_bind(const struct sockaddr *sin_addr,
+ const socklen_t addrlen,
+ int orig_sd,
+ int *sdp_sd, int *tcp_sd, int semantics)
+{
+ unsigned int yes = 1;
+ int ret = -1;
+ int sret = -1;
+ int domain, sdp_domain;
+
+ /* need to obtain the address family from the fd */
+ domain = get_sock_domain(orig_sd);
+ if (domain == -1) {
+ errno = EFAULT;
+ ret = -1;
+ goto done;
+ }
+
+ sdp_domain = get_sdp_domain(domain);
+ if (sdp_domain < 0) {
+ errno = EFAULT;
+ goto done;
+ }
+
+ __sdp_log(2, "check_legal_bind: binding two temporary sockets\n");
+ *sdp_sd = _socket_funcs.socket(sdp_domain, SOCK_STREAM, IPPROTO_TCP);
+ if (*sdp_sd < 0) {
+ __sdp_log(9, "Error check_legal_bind: " "creating SDP socket failed\n");
+ goto done;
+ }
+
+ __sdp_log(2, "check_legal_bind: reusing <%d> \n", *sdp_sd);
+ sret =
+ _socket_funcs.setsockopt(*sdp_sd, SOL_SOCKET, SO_REUSEADDR, &yes,
+ sizeof(yes));
+ if (sret < 0) {
+ __sdp_log(9, "Error bind: Could not setsockopt sdp_sd\n");
+ }
+
+ *tcp_sd = _socket_funcs.socket(domain, SOCK_STREAM, IPPROTO_TCP);
+ if (*tcp_sd < 0) {
+ __sdp_log(9, "Error check_legal_bind: "
+ "creating second socket failed:%s\n", strerror(errno));
+ _socket_funcs.close(*sdp_sd);
+ goto done;
+ }
+
+ __sdp_log(2, "check_legal_bind: reusing <%d> \n", *tcp_sd);
+ sret =
+ _socket_funcs.setsockopt(*tcp_sd, SOL_SOCKET, SO_REUSEADDR, &yes,
+ sizeof(yes));
+ if (sret < 0) {
+ __sdp_log(9, "Error bind: Could not setsockopt tcp_sd\n");
+ }
+
+ __sdp_log(1, "check_legal_bind: binding SDP socket\n");
+ ret = __bind_semantics(*sdp_sd, sin_addr, addrlen, semantics);
+ if (ret < 0) {
+ /* bind() for sdp socket failed. It is acceptable only if
+ * the IP is not part of IB network. */
+ int err;
+ socklen_t len = sizeof(int);
+
+ if (EADDRINUSE != errno)
+ goto done;
+#ifdef __linux__
+ if (-1 == getsockopt(*sdp_sd, SOL_TCP, SDP_LAST_BIND_ERR, &err, &len)) {
+ __sdp_log(9, "Error check_legal_bind:getsockopt: %s\n",
+ strerror(errno));
+ goto done;
+ }
+#else
+ err = -errno;
+#endif
+ if (-ENOENT != err) {
+ /* bind() failed due to real error. Can't continue */
+ __sdp_log(9, "Error check_legal_bind: "
+ "binding SDP socket failed:%s\n", strerror(errno));
+ _socket_funcs.close(*sdp_sd);
+ _socket_funcs.close(*tcp_sd);
+
+ /* TCP and SDP without library return EINVAL */
+ if (errno == EADDRINUSE)
+ errno = EINVAL;
+
+ goto done;
+ }
+ /* IP is ETH, not IB, so can't bind() to sdp socket */
+ /* Continue only with TCP */
+ _socket_funcs.close(*sdp_sd);
+ *sdp_sd = -1;
+ }
+
+ __sdp_log(1, "check_legal_bind: binding TCP socket\n");
+ ret = __bind_semantics(*tcp_sd, sin_addr, addrlen, semantics);
+ if (ret < 0) {
+ __sdp_log(9, "Error check_legal_bind: "
+ "binding TCP socket failed:%s\n", strerror(errno));
+ if (-1 != *sdp_sd)
+ _socket_funcs.close(*sdp_sd);
+ _socket_funcs.close(*tcp_sd);
+ goto done;
+ }
+ ret = 0;
+ __sdp_log(2, "check_legal_bind: result:<%d>\n", ret);
+done:
+ return ret;
+}
+
+/* ========================================================================= */
+/*..close_and_bind - close an open fd and bind another one immediately */
+static int
+close_and_bind(int old_sd,
+ int new_sd,
+ const struct sockaddr *addr, socklen_t addrlen, int semantics)
+{
+ int ret;
+
+ __sdp_log(2, "close_and_bind: closing <%d> binding <%d>\n", old_sd, new_sd);
+ ret = _socket_funcs.close(old_sd);
+ if (ret < 0) {
+ __sdp_log(9, "Error bind: Could not close old_sd\n");
+ goto done;
+ }
+
+ ret = __bind_semantics(new_sd, addr, addrlen, semantics);
+ if (ret < 0)
+ __sdp_log(9, "Error bind: Could not bind new_sd\n");
+
+done:
+ __sdp_log(2, "close_and_bind: returning <%d>\n", ret);
+ return ret;
+}
+
+/* ========================================================================= */
+/*..bind -- replacement bind call. */
+/*
+ As we do not know the role of this socket yet so we cannot choose AF.
+ We need to be able to handle shadow too.
+ SDP sockets (may be shadow or not) must be using converted address
+
+ Since there is no way to "rebind" a socket we have to avoid "false" bind:
+ 1. When the given address for the bind includes a port we need to
+ guarantee the port is free on both address families. We do that
+ by creating temporary sockets and biding them first. Then we close and
+ re-use the address on the real sockets.
+ 2. When ANY_PORT is requested we need to make sure the port we obtain from
+ the first address family is also free on the second one. We use temporary
+ sockets for that task too. We loop several times to find such common
+ available socket
+*/
+static int
+__perform_bind(int fd,
+ const struct sockaddr *addr, socklen_t addrlen, int semantics)
+{
+ int shadow_fd;
+ struct sockaddr_in *sin_addr = (struct sockaddr_in *) addr;
+ int ret, sret = -1;
+ char buf[MAX_ADDR_STR_LEN];
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.bind) {
+ __sdp_log(9, "Error bind: no implementation for bind found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+
+ if ((addr == NULL) || is_invalid_addr(addr)) {
+ errno = EFAULT;
+ __sdp_log(9, "Error bind: illegal address provided\n");
+ return -1;
+ }
+
+ if (get_addr_str(addr, buf, MAX_ADDR_STR_LEN)) {
+ __sdp_log(9, "Error bind: provided illegal address: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ __sdp_log(2, "BIND: <%s:%d:%d> type <%d> IP <%s> port <%d>\n",
+ program_invocation_short_name, fd, shadow_fd,
+ sin_addr->sin_family, buf, ntohs(sin_addr->sin_port));
+
+ if (get_is_sdp_socket(fd)) {
+ __sdp_log(1, "BIND: binding SDP socket:<%d>\n", fd);
+ ret = __bind_semantics(fd, addr, addrlen, semantics);
+ goto done;
+ } else if (shadow_fd != -1) {
+ /* has shadow */
+ /* we need to validate the given address or find a common port
+ * so we use the following tmp address and sockets */
+ struct sockaddr_storage tmp_addr;
+ int sdp_sd = -1, tcp_sd = -1, port;
+
+ memcpy(&tmp_addr, addr, addrlen);
+ ret = 0;
+ if (ntohs(sin_addr->sin_port) == 0) {
+ /* When we get ANY_PORT we need to make sure that both TCP
+ * and SDP sockets will use the same port */
+
+ port = find_free_port(addr, addrlen, fd, &sdp_sd, &tcp_sd, semantics);
+ if (port < 0) {
+ ret = -1;
+ __sdp_log(9, "BIND: Failed to find common free port\n");
+ /* We cannot bind both tcp and sdp on the same port, we will close
+ * the sdp and continue with tcp only */
+ goto done;
+ } else {
+ /* copy the port to the tmp address */
+ set_addr_port_num((struct sockaddr *) &tmp_addr, port);
+ }
+ } else {
+ /* have a shadow but requested specific port - check that we
+ * can actually bind the two addresses and then reuse */
+ ret = check_legal_bind(addr, addrlen, fd, &sdp_sd, &tcp_sd, semantics);
+ if (ret < 0) {
+ __sdp_log(9, "Error bind: "
+ "Provided address can not bind on the two sockets\n");
+ }
+ }
+
+ /* if we fail to find a common port or given address can not be used
+ * we return error */
+ if (ret < 0) {
+ /* Temporary sockets already closed by check_legal_bind or
+ * find_free_port */
+ errno = EADDRINUSE;
+ goto done;
+ }
+
+ /* close temporary sockets and reuse their address */
+ /* HACK: close_and_bind might race with other applications. */
+ /* When the race occur we return EADDRINUSE */
+ ret = close_and_bind(tcp_sd, fd, (struct sockaddr *) &tmp_addr,
+ addrlen, semantics);
+ if (ret < 0) {
+ __sdp_log(9, "Error bind: " "Could not close_and_bind TCP side\n");
+ if (-1 != sdp_sd)
+ _socket_funcs.close(sdp_sd);
+ goto done;
+ }
+
+ if (-1 != sdp_sd) {
+ ret = close_and_bind(sdp_sd, shadow_fd, (struct sockaddr *) &tmp_addr,
+ addrlen, semantics);
+
+ if (ret < 0) {
+ __sdp_log(9,
+ "Error bind: " "Could not close_and_bind sdp side\n");
+ goto done;
+ }
+ }
+ goto done;
+ }
+
+ /* we can only get here on single TCP socket */
+ __sdp_log(1, "BIND: binding TCP socket:<%d>\n", fd);
+ ret = __bind_semantics(fd, addr, addrlen, semantics);
+
+done:
+ __sdp_log(2, "BIND: <%s:%d:%d> result <%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd, ret, sret);
+
+ return ret;
+} /* bind */
+
+
+int bind(int fd, const struct sockaddr *my_addr, socklen_t addrlen)
+{
+ return __perform_bind(fd, my_addr, addrlen, SOCKET_SEMANTIC_DEFAULT);
+}
+
+#ifdef SOLARIS_BUILD
+int __xnet_bind(int fd, const struct sockaddr *my_addr, socklen_t addrlen)
+{
+ return __perform_bind(fd, my_addr, addrlen, SOCKET_SEMANTIC_XNET);
+}
+#endif
+
+
+/* ========================================================================= */
+/*..connect -- replacement connect call. */
+/*
+ Given the connect address we can take out AF decision
+ if target AF == both it means SDP and fall back to TCP
+ if any connect worked we are fine
+*/
+static inline int
+__connect_semantics(int fd,
+ const struct sockaddr *serv_addr,
+ socklen_t addrlen, int semantics)
+{
+ return
+#ifdef SOLARIS_BUILD
+ (semantics == SOCKET_SEMANTIC_XNET) ?
+ _socket_xnet_funcs.connect(fd, serv_addr, addrlen) :
+#endif
+ _socket_funcs.connect(fd, serv_addr, addrlen);
+}
+
+static int
+__perform_connect(int fd, const struct sockaddr *serv_addr,
+ socklen_t addrlen, int semantics)
+{
+ struct sockaddr_in *serv_sin = (struct sockaddr_in *) serv_addr;
+ char buf[MAX_ADDR_STR_LEN];
+ int shadow_fd;
+ int ret = -1, dup_ret;
+ use_family_t target_family;
+ int fopts;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.connect) {
+ __sdp_log(9, "Error connect: no implementation for connect found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+
+ if ((serv_addr == NULL) || is_invalid_addr(serv_addr)) {
+ errno = EFAULT;
+ __sdp_log(9, "Error connect: illegal address provided\n");
+ return -1;
+ }
+
+ if (get_addr_str(serv_addr, buf, MAX_ADDR_STR_LEN)) {
+ __sdp_log(9, "Error connect: provided illegal address: %s\n",
+ strerror(errno));
+ return EADDRNOTAVAIL;
+ }
+
+ __sdp_log(2, "CONNECT: <%s:%d:%d> domain <%d> IP <%s> port <%d>\n",
+ program_invocation_short_name, fd, shadow_fd,
+ serv_sin->sin_family, buf, ntohs(serv_sin->sin_port));
+
+
+ /* obtain the target address family */
+ target_family = __sdp_match_connect(serv_addr, addrlen);
+
+ /* if we do not have a shadow - just do the work */
+ if (shadow_fd == -1) {
+ __sdp_log(1, "CONNECT: connectingthrough %s\n",
+ get_is_sdp_socket(fd) ? "SDP" : "TCP");
+ ret = __connect_semantics(fd, serv_addr, addrlen, semantics);
+ if ((ret == 0) || (errno == EINPROGRESS)) {
+ __sdp_log(7, "CONNECT: connected SDP fd:%d to:%s port %d\n",
+ fd, buf, ntohs(serv_sin->sin_port));
+ }
+ goto done;
+ }
+
+ if ((target_family == USE_SDP) || (target_family == USE_BOTH)) {
+ /* NOTE: the entire if sequence is negative logic */
+ __sdp_log(1, "CONNECT: connecting SDP fd:%d\n", shadow_fd);
+
+ /* make the socket blocking on shadow SDP */
+ fopts = _socket_funcs.fcntl(shadow_fd, F_GETFL);
+ if ((target_family == USE_BOTH) && (fopts & O_NONBLOCK)) {
+ __sdp_log(1,
+ "CONNECT: shadow_fd <%d> will be blocking during connect\n",
+ shadow_fd);
+ _socket_funcs.fcntl(shadow_fd, F_SETFL, fopts & (~O_NONBLOCK));
+ }
+
+ ret = __connect_semantics(shadow_fd, serv_addr, addrlen, semantics);
+ if ((ret < 0) && (errno != EINPROGRESS)) {
+ __sdp_log(9, "Error connect: "
+ "failed for SDP fd:%d with error:%m\n", shadow_fd);
+ } else {
+ __sdp_log(7, "CONNECT: connected SDP fd:%d to:%s port %d\n",
+ fd, buf, ntohs(serv_sin->sin_port));
+ }
+
+ /* restore socket options */
+ _socket_funcs.fcntl(shadow_fd, F_SETFL, fopts);
+
+ /* if target is SDP or we succeeded we need to dup SDP fd into TCP fd */
+ if ((target_family == USE_SDP) || (ret >= 0)) {
+ dup_ret = replace_fd_with_its_shadow(fd);
+ if (dup_ret < 0) {
+ __sdp_log(9, "Error connect: "
+ "failed to dup2 shadow into orig fd:%d\n", fd);
+ ret = dup_ret;
+ } else {
+ /* we can skip the TCP option if we are done */
+ __sdp_log(1, "CONNECT: "
+ "matched SDP fd:%d so shadow dup into TCP\n", fd);
+ goto done;
+ }
+ }
+ }
+
+ if ((target_family == USE_TCP) || (target_family == USE_BOTH)) {
+ __sdp_log(1, "CONNECT: connecting TCP fd:%d\n", fd);
+ ret = __connect_semantics(fd, serv_addr, addrlen, semantics);
+ if ((ret < 0) && (errno != EINPROGRESS))
+ __sdp_log(9, "Error connect: for TCP fd:%d failed with error:%m\n",
+ fd);
+ else
+ __sdp_log(7, "CONNECT: connected TCP fd:%d to:%s port %d\n",
+ fd, buf, ntohs(serv_sin->sin_port));
+
+ if ((target_family == USE_TCP) || (ret >= 0) || (errno == EINPROGRESS)) {
+ if (cleanup_shadow(fd) < 0)
+ __sdp_log(9,
+ "Error connect: failed to cleanup shadow for fd:%d\n",
+ fd);
+ }
+ }
+
+done:
+ __sdp_log(2, "CONNECT: <%s:%d:%d> result <%d>\n",
+ program_invocation_short_name, fd, shadow_fd, ret);
+
+ return ret;
+} /* connect */
+
+int connect(int fd, const struct sockaddr *serv_addr, socklen_t addrlen)
+{
+ return __perform_connect(fd, serv_addr, addrlen, SOCKET_SEMANTIC_DEFAULT);
+}
+
+#if defined( SOLARIS_BUILD )
+int __xnet_connect(int fd, const struct sockaddr *serv_addr, socklen_t addrlen)
+{
+ return __perform_connect(fd, serv_addr, addrlen, SOCKET_SEMANTIC_XNET);
+}
+#endif
+
+/* ========================================================================= */
+/*..listen -- replacement listen call. */
+/*
+ Now we know our role (passive/server) and our address so we can get AF.
+ If both we should try listening on both
+*/
+
+static inline int __listen_semantics(int fd, int backlog, int semantics)
+{
+ return
+#ifdef SOLARIS_BUILD
+ (semantics == SOCKET_SEMANTIC_XNET) ?
+ _socket_xnet_funcs.listen(fd, backlog) :
+#endif
+ _socket_funcs.listen(fd, backlog);
+}
+
+static int __perform_listen(int fd, int backlog, int semantics)
+{
+ use_family_t target_family;
+ int shadow_fd;
+ int ret = 0, sret = 0;
+ struct sockaddr_storage tmp_sin;
+ socklen_t tmp_sinlen = sizeof(tmp_sin);
+ struct sockaddr_in *sin4 = (struct sockaddr_in *) &tmp_sin;
+ char buf[MAX_ADDR_STR_LEN];
+ int actual_port;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.listen) {
+ __sdp_log(9, "Error listen: no implementation for listen found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+ __sdp_log(2, "LISTEN: <%s:%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd);
+
+ /* if there is no shadow - simply call listen */
+ if (shadow_fd == -1) {
+ __sdp_log(1, "LISTEN: calling listen on fd:%d\n", fd);
+ ret = __listen_semantics(fd, backlog, semantics);
+ goto done;
+ }
+
+ /* we need to obtain the address from the fd */
+ if (_socket_funcs.getsockname(fd, (struct sockaddr *) &tmp_sin, &tmp_sinlen)
+ < 0) {
+ __sdp_log(9, "Error listen: getsockname return <%d> for TCP socket\n",
+ errno);
+ errno = EADDRNOTAVAIL;
+ sret = -1;
+ goto done;
+ }
+
+ if (get_addr_str((struct sockaddr *) &tmp_sin, buf, MAX_ADDR_STR_LEN)) {
+ __sdp_log(9, "Error listen: provided illegal address: %s\n",
+ strerror(errno));
+ }
+
+ __sdp_log(2, "LISTEN: <%s:%d:%d> domain <%d> IP <%s> port <%d>\n",
+ program_invocation_short_name, fd, shadow_fd,
+ sin4->sin_family, buf, ntohs(sin4->sin_port));
+
+ target_family =
+ __sdp_match_listen((struct sockaddr *) &tmp_sin, sizeof(tmp_sin));
+
+ /*
+ * in case of an implicit bind and "USE_BOTH" rule we need to first bind the
+ * two sockets to the same port number
+ */
+ actual_port = ntohs(sin4->sin_port);
+
+ /* do we need to implicit bind both */
+ if ((actual_port == 0) && (target_family == USE_BOTH)) {
+ int sdp_sd = -1, tcp_sd = -1;
+
+ actual_port = find_free_port((struct sockaddr *) &tmp_sin, tmp_sinlen,
+ fd, &sdp_sd, &tcp_sd, semantics);
+ if (actual_port < 0) {
+ ret = -1;
+ __sdp_log(8, "LISTEN: Failed to find common free port. Only TCP will be used.\n");
+ target_family = USE_TCP;
+ } else {
+ /* copy the port to the tmp address */
+ set_addr_port_num((struct sockaddr *) sin4, actual_port);
+
+ __sdp_log(2, "LISTEN: BOTH on IP <%s> port <%d>\n",
+ buf, actual_port);
+ /* perform the bind */
+ ret = close_and_bind(tcp_sd, fd, (struct sockaddr *) sin4,
+ tmp_sinlen, semantics);
+ if (ret < 0) {
+ __sdp_log(9, "Error listen: "
+ "Could not close_and_bind TCP side\n");
+ }
+
+ ret = close_and_bind(sdp_sd, shadow_fd, (struct sockaddr *) sin4,
+ tmp_sinlen, semantics);
+ if (ret < 0) {
+ __sdp_log(9, "Error listen: "
+ "Could not close_and_bind SDP side\n");
+ }
+ }
+ }
+
+ if ((target_family == USE_TCP) || (target_family == USE_BOTH)) {
+ __sdp_log(1, "LISTEN: calling listen on TCP fd:%d\n", fd);
+ ret = __listen_semantics(fd, backlog, semantics);
+ if (ret < 0) {
+ __sdp_log(9, "Error listen: failed with code <%d> on TCP fd:<%d>\n",
+ errno, fd);
+ } else {
+ __sdp_log(7, "LISTEN: fd:%d listening on TCP bound to:%s port:%d\n",
+ fd, buf, actual_port);
+ }
+ }
+
+ if ((target_family == USE_SDP) || (target_family == USE_BOTH)) {
+ __sdp_log(1, "LISTEN: calling listen on SDP fd:<%d>\n", shadow_fd);
+ sret = __listen_semantics(shadow_fd, backlog, semantics);
+ if (sret < 0) {
+ __sdp_log(9, "Error listen: failed with code <%d> SDP fd:<%d>\n",
+ errno, shadow_fd);
+ } else {
+ __sdp_log(7, "LISTEN: fd:%d listening on SDP bound to:%s port:%d\n",
+ fd, buf, actual_port);
+ }
+ }
+
+ /* cleanup the un-needed shadow if TCP and did not fail */
+ if ((target_family == USE_TCP) && (ret >= 0)) {
+ __sdp_log(1, "LISTEN: cleaning up shadow SDP\n");
+ if (cleanup_shadow(fd) < 0)
+ __sdp_log(9, "Error listen: failed to cleanup shadow for fd:%d\n",
+ fd);
+ }
+
+ /* cleanup the TCP socket and replace with SDP */
+ if ((target_family == USE_SDP) && (sret >= 0)) {
+ __sdp_log(1, "LISTEN: cleaning TCP socket and dup2 SDP into it\n");
+ if (0 > (sret = replace_fd_with_its_shadow(fd)))
+ __sdp_log(9, "Error listen: "
+ "failed to dup2 shadow into orig fd:%d\n", fd);
+ }
+
+done:
+ __sdp_log(2, "LISTEN: <%s:%d:%d> result <%d>\n",
+ program_invocation_short_name, fd, shadow_fd, ret);
+ /* its a success only if both are ok */
+ if (ret < 0)
+ return (ret);
+ if (sret < 0)
+ return (sret);
+ return 0;
+} /* listen */
+
+int listen(int fd, int backlog)
+{
+ return __perform_listen(fd, backlog, SOCKET_SEMANTIC_DEFAULT);
+}
+
+#ifdef SOLARIS_BUILD
+int __xnet_listen(int fd, int backlog)
+{
+ return __perform_listen(fd, backlog, SOCKET_SEMANTIC_XNET);
+}
+#endif
+
+/* ========================================================================= */
+/*..close -- replacement close call. */
+int close(int fd)
+{
+ int shadow_fd;
+ int ret;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.close) {
+ __sdp_log(9, "Error close: no implementation for close found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+
+ __sdp_log(2, "CLOSE: <%s:%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd);
+
+ if (shadow_fd != -1) {
+ __sdp_log(1, "CLOSE: closing shadow fd:<%d>\n", shadow_fd);
+ if (cleanup_shadow(fd) < 0)
+ __sdp_log(9, "Error close: failed to cleanup shadow for fd:%d\n",
+ fd);
+ }
+
+ init_extra_attribute(fd);
+ ret = _socket_funcs.close(fd);
+ __sdp_log(2, "CLOSE: <%s:%d:%d> result <%d>\n",
+ program_invocation_short_name, fd, shadow_fd, ret);
+ return ret;
+} /* close */
+
+/* ========================================================================= */
+/*..dup -- replacement dup call. */
+/* we duplicate the fd and its shadow if exists - ok if the main worked */
+int dup(int fd)
+{
+ int newfd, new_shadow_fd = -1;
+ int shadow_fd;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.dup) {
+ __sdp_log(9, "Error dup: no implementation for dup found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+
+ __sdp_log(2, "DUP: <%s:%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd);
+
+ __sdp_log(1, "DUP: duplication fd:<%d>\n", fd);
+ newfd = _socket_funcs.dup(fd);
+
+ if (newfd == fd)
+ return (fd);
+
+ if (!is_valid_fd(newfd)) {
+ __sdp_log(9, "Error dup: new fd <%d> out of range.\n", newfd);
+ } else {
+ /* copy attributes from old fd */
+ libsdp_fd_attributes[newfd] = libsdp_fd_attributes[fd];
+ libsdp_fd_attributes[newfd].shadow_fd = -1;
+
+ if (shadow_fd != -1) {
+ __sdp_log(1, "DUP: duplication shadow fd:<%d>\n", shadow_fd);
+ new_shadow_fd = _socket_funcs.dup(shadow_fd);
+ if ((new_shadow_fd > max_file_descriptors) || (new_shadow_fd < 0)) {
+ __sdp_log(9, "Error dup: new shadow fd <%d> out of range.\n",
+ new_shadow_fd);
+ } else {
+ libsdp_fd_attributes[new_shadow_fd] =
+ libsdp_fd_attributes[shadow_fd];
+ libsdp_fd_attributes[newfd].shadow_fd = new_shadow_fd;
+ }
+ } /* shadow exists */
+ }
+
+ __sdp_log(2, "DUP: <%s:%d:%d> return <%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd, newfd,
+ new_shadow_fd);
+
+ return newfd;
+} /* dup */
+
+/* ========================================================================= */
+/*..dup2 -- replacement dup2 call. */
+/* since only the main new fd is given we only move the shadow if exists */
+int dup2(int fd, int newfd)
+{
+ int shadow_fd;
+ int shadow_newfd;
+ int new_shadow_fd = -1;
+ int ret = 0;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.dup2) {
+ __sdp_log(9, "Error dup2: no implementation for dup2 found\n");
+ return -1;
+ }
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+ shadow_newfd = get_shadow_fd_by_fd(newfd);
+
+ __sdp_log(2, "DUP2: <%s:%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd);
+
+ if (newfd == fd) {
+ __sdp_log(1, "DUP2: skip duplicating fd:<%d> into:<%d>\n", fd, newfd);
+ goto done;
+ }
+
+ /* dup2 closes the target file desc if it is a valid fd */
+ if (shadow_newfd != -1) {
+ __sdp_log(1, "DUP2: closing newfd:<%d> shadow:<%d>\n", newfd,
+ shadow_newfd);
+ ret = _socket_funcs.close(shadow_newfd);
+ if (ret != 0) {
+ __sdp_log(9,
+ "DUP2: fail to close newfd:<%d> shadow:<%d> with: %d %s\n",
+ newfd, shadow_newfd, ret, strerror(errno));
+ }
+ }
+
+ __sdp_log(1, "DUP2: duplicating fd:<%d> into:<%d>\n", fd, newfd);
+ newfd = _socket_funcs.dup2(fd, newfd);
+ if ((newfd > max_file_descriptors) || (newfd < 0)) {
+ __sdp_log(9, "Error dup2: new fd <%d> out of range.\n", newfd);
+ } else {
+ /* copy attributes from old fd */
+ libsdp_fd_attributes[fd].shadow_fd = -1;
+ libsdp_fd_attributes[newfd] = libsdp_fd_attributes[fd];
+
+ /* if it had a shadow create a new shadow */
+ if (shadow_fd != -1) {
+ __sdp_log(1, "DUP2: duplication shadow fd:<%d>\n", shadow_fd);
+ new_shadow_fd = _socket_funcs.dup(shadow_fd);
+ if ((new_shadow_fd > max_file_descriptors) || (new_shadow_fd < 0)) {
+ __sdp_log(9, "Error dup2: new shadow fd <%d> out of range.\n",
+ new_shadow_fd);
+ } else {
+ libsdp_fd_attributes[new_shadow_fd] =
+ libsdp_fd_attributes[shadow_fd];
+ libsdp_fd_attributes[newfd].shadow_fd = new_shadow_fd;
+ }
+ } /* newfd is ok */
+ }
+
+done:
+ __sdp_log(2, "DUP2: <%s:%d:%d> return <%d:%d>\n",
+ program_invocation_short_name, fd, shadow_fd, newfd,
+ new_shadow_fd);
+
+ return newfd;
+} /* dup */
+
+/* ========================================================================= */
+/*..getsockname -- replacement getsocknanme call. */
+int getsockname(int fd, struct sockaddr *name, socklen_t * namelen)
+{
+ int ret = 0;
+ char buf[MAX_ADDR_STR_LEN];
+
+ if (init_status == 0)
+ __sdp_init();
+
+ /*
+ * ensure the SDP protocol family is not exposed to the user, since
+ * this is meant to be a transparency layer.
+ */
+ if (NULL == _socket_funcs.getsockname) {
+ __sdp_log(9,
+ "Error getsockname: no implementation for getsockname found\n");
+ return -1;
+ }
+
+ /* double check provided pointers */
+ if ((name == NULL) || is_invalid_addr(name)) {
+ errno = EFAULT;
+ __sdp_log(9, "Error getsockname: illegal address provided\n");
+ return -1;
+ }
+
+ if ((namelen != NULL) && is_invalid_addr(namelen)) {
+ errno = EFAULT;
+ __sdp_log(9, "Error getsockname: illegal address length pointer provided\n");
+ return -1;
+ }
+
+ __sdp_log(2, "GETSOCKNAME <%s:%d>\n", program_invocation_short_name, fd);
+
+ ret = _socket_funcs.getsockname(fd, name, namelen);
+
+ if (__sdp_log_get_level() <= 1) {
+ if (get_addr_str(name, buf, MAX_ADDR_STR_LEN)) {
+ __sdp_log(1, "GETSOCKNAME: " "address is illegal\n");
+ } else {
+ __sdp_log(1, "GETSOCKNAME: address is:%s port:%d\n", buf,
+ ntohs(((struct sockaddr_in *) name)->sin_port));
+ }
+ }
+ __sdp_log(2, "GETSOCKNAME <%s:%d> result <%d>\n",
+ program_invocation_short_name, fd, ret);
+
+ return ret;
+} /* getsockname */
+
+/* ========================================================================= */
+/*..getpeername -- replacement getpeername call. */
+int getpeername(int fd, struct sockaddr *name, socklen_t * namelen)
+{
+ int ret = 0;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.getpeername) {
+ __sdp_log(9, "Error getpeername: "
+ "no implementation for getpeername found\n");
+ return -1;
+ }
+
+ /* double check provided pointers */
+ if ((name == NULL) || is_invalid_addr(name)) {
+ errno = EFAULT;
+ __sdp_log(9, "Error getsockname: illegal address provided\n");
+ return -1;
+ }
+
+ if ((namelen != NULL) && is_invalid_addr(namelen)) {
+ errno = EFAULT;
+ __sdp_log(9,
+ "Error getsockname: illegal address length pointer provided\n");
+ return -1;
+ }
+
+ __sdp_log(2, "GETPEERNAME <%s:%d>\n", program_invocation_short_name, fd);
+
+ ret = _socket_funcs.getpeername(fd, name, namelen);
+
+ __sdp_log(2, "GETPEERNAME <%s:%d> result <%d:%d> family=%d s_addr=%d\n",
+ program_invocation_short_name, fd, ret,
+ (!(0 > ret) ? 0 : -1), name->sa_family,
+ ((struct sockaddr_in *) name)->sin_addr.s_addr);
+
+ return ret;
+} /* getpeername */
+
+
+
+/* ========================================================================= */
+/*..accept -- replacement accept call. */
+/*
+ If we have a shadow we need to decide which socket we want to accept on
+ so we select first and then give priority based on previous selection
+*/
+int accept(int fd, struct sockaddr *addr, socklen_t * addrlen)
+{
+ int shadow_fd;
+ int ret = 0;
+ fd_set fds;
+ socklen_t saved_addrlen = 0;
+ int fopts;
+ char buf[MAX_ADDR_STR_LEN];
+
+ if (init_status == 0)
+ __sdp_init();
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+
+ /*
+ * ensure the SDP protocol family is not exposed to the user, since
+ * this is meant to be a transparency layer.
+ */
+ if (NULL == _socket_funcs.accept) {
+ __sdp_log(9, "Error accept: no implementation for accept found\n");
+ return -1;
+ }
+
+ /* double check provided pointers */
+ if ((addr != NULL) && is_invalid_addr(addr)) {
+ errno = EINVAL;
+ __sdp_log(9, "Error accept: illegal address provided\n");
+ return -1;
+ }
+
+ if ((addrlen != NULL) && is_invalid_addr(addrlen)) {
+ errno = EINVAL;
+ __sdp_log(9, "Error accept: illegal address length pointer provided\n");
+ return -1;
+ }
+
+ if (addr && addrlen)
+ saved_addrlen = *addrlen;
+
+ __sdp_log(2, "ACCEPT: <%s:%d>\n", program_invocation_short_name, fd);
+
+ if (shadow_fd == -1) {
+ fopts = _socket_funcs.fcntl(fd, F_GETFL);
+ __sdp_log(1, "ACCEPT: fd <%d> opts are <0x%x>\n", fd, fopts);
+
+ __sdp_log(7, "ACCEPT: accepting on single fd:<%d>\n", fd);
+ ret = _socket_funcs.accept(fd, addr, addrlen);
+ if (ret < 0) {
+ if (!(fopts & O_NONBLOCK && errno == EWOULDBLOCK))
+ __sdp_log(9, "Error accept: accept returned :<%d> %s\n",
+ ret, strerror(errno));
+ } else {
+ set_is_sdp_socket(ret, get_is_sdp_socket(fd));
+ }
+ } else {
+
+ fopts = _socket_funcs.fcntl(shadow_fd, F_GETFL);
+ __sdp_log(1, "ACCEPT: shadow_fd <%d> opts are <0x%x>\n",
+ shadow_fd, fopts);
+
+ /* we need different behavior for NONBLOCK or signal IO and BLOCK */
+ if ((fopts > 0) && (fopts & (O_NONBLOCK | FASYNC))) {
+ __sdp_log(1, "ACCEPT: accepting (nonblock) on SDP fd:<%d>\n", shadow_fd);
+
+ ret = _socket_funcs.accept(shadow_fd, addr, addrlen);
+ if (ret >= 0) {
+ set_is_sdp_socket(ret, 1);
+
+ __sdp_log(7, "ACCEPT: accepted (nonblock) SDP fd:<%d>\n",
+ shadow_fd);
+ } else {
+ __sdp_log(1, "ACCEPT: accept on SDP fd:<%d> return:%d errno:%d\n",
+ shadow_fd, ret, errno);
+
+ __sdp_log(1, "ACCEPT: accepting (nonblock) on TCP fd:<%d>\n", fd);
+ ret = _socket_funcs.accept(fd, addr, addrlen);
+ if (ret >= 0) {
+ __sdp_log(7, "ACCEPT: accepted (nonblock) TCP fd:<%d>\n",
+ shadow_fd);
+ } else {
+ __sdp_log(1, "ACCEPT: accept on TCP fd:<%d> "
+ "return:%d errno:%d\n", fd, ret, errno);
+ }
+ }
+ } else {
+ __sdp_log(1, "ACCEPT: selecting both fd:<%d> and shadow:<%d>\n",
+ fd, shadow_fd);
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ FD_SET(shadow_fd, &fds);
+ ret =
+ _socket_funcs.select(1 + ((fd > shadow_fd) ? fd : shadow_fd),
+ &fds, NULL, NULL, NULL);
+ if (ret >= 0) {
+ if (last_accept_was_tcp(fd) == 0) {
+ if (FD_ISSET(fd, &fds)) {
+ set_last_accept(fd, 1);
+ __sdp_log(7, "ACCEPT: accepting on TCP fd:<%d>\n", fd);
+ ret = _socket_funcs.accept(fd, addr, addrlen);
+ } else {
+ __sdp_log(7, "ACCEPT: accepting on SDP fd:<%d>\n",
+ shadow_fd);
+ ret = _socket_funcs.accept(shadow_fd, addr, addrlen);
+ if (ret >= 0)
+ set_is_sdp_socket(ret, 1);
+ }
+ } else {
+ if (FD_ISSET(shadow_fd, &fds)) {
+ set_last_accept(fd, 1);
+ __sdp_log(7, "ACCEPT: accepting on SDP fd:<%d>\n",
+ shadow_fd);
+ ret = _socket_funcs.accept(shadow_fd, addr, addrlen);
+ if (ret >= 0)
+ set_is_sdp_socket(ret, 1);
+ } else {
+ __sdp_log(7, "ACCEPT: accepting on TCP fd:<%d>\n", fd);
+ ret = _socket_funcs.accept(fd, addr, addrlen);
+ }
+ }
+ } else {
+ if (errno != EINTR) {
+ __sdp_log(9,
+ "Error accept: select returned :<%d> (%d) %s\n",
+ ret, errno, strerror(errno));
+ } else {
+ __sdp_log(1, "ACCEPT: select returned :<%d> (%d) %s\n",
+ ret, errno, strerror(errno));
+ }
+ }
+ } /* blocking mode */
+ } /* shadow fd */
+
+ if ((__sdp_log_get_level() <= 1) && (ret >= 0) && addr && addrlen) {
+ get_addr_str(addr, buf, *addrlen);
+ __sdp_log(1, "ACCEPT: accepted from:%s port:%d into fd:%d\n",
+ buf, ntohs(((struct sockaddr_in *) addr)->sin_port), ret);
+ }
+ __sdp_log(2, "ACCEPT: <%s:%d> return <%d>\n",
+ program_invocation_short_name, fd, ret);
+
+ return ret;
+} /* accept */
+
+/* ========================================================================= */
+/*..select -- replacement socket call. */
+/*
+ if we have shadow we must select on it too - which requires a hack back
+ and forth
+*/
+int
+select(int n,
+ fd_set * readfds,
+ fd_set * writefds, fd_set * exceptfds, struct timeval *timeout)
+{
+ int shadow_fd;
+ int ret;
+ int current;
+ int maxi = 0;
+ fd_set new_fds;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.select) {
+ __sdp_log(9, "Error select: no implementation for select found\n");
+ return -1;
+ }
+
+ __sdp_log(2, "SELECT: <%s:%d>\n", program_invocation_short_name, n);
+
+ /* if we do not read - nothing to do */
+ if (readfds == NULL) {
+ ret = _socket_funcs.select(n, readfds, writefds, exceptfds, timeout);
+ goto done;
+ }
+
+ FD_ZERO(&new_fds);
+ if (n > 0) {
+ maxi = n - 1;
+ }
+
+ /* add shadow bits */
+ for (current = 0; current < n; current++) {
+ if (FD_ISSET(current, readfds)) {
+ FD_SET(current, &new_fds);
+ if (current > maxi) {
+ maxi = current;
+ }
+ shadow_fd = get_shadow_fd_by_fd(current);
+ if (shadow_fd != -1) {
+ __sdp_log(1,
+ "SELECT: adding fd:<%d> shadow_fd:<%d> to readfs\n",
+ current, shadow_fd);
+ FD_SET(shadow_fd, &new_fds);
+ if (shadow_fd > maxi) {
+ maxi = shadow_fd;
+ }
+ }
+ }
+ }
+
+ __sdp_log(1, "SELECT: invoking select n=<%d>\n", 1 + maxi);
+ ret = _socket_funcs.select(1 + maxi,
+ &new_fds, writefds, exceptfds, timeout);
+
+ /* remove the count and bits of the shadows */
+ if (ret >= 0) {
+ for (current = 0; current < n; current++) {
+ shadow_fd = get_shadow_fd_by_fd(current);
+ if (shadow_fd == -1) {
+ if (FD_ISSET(current, readfds) &&
+ FD_ISSET(current, &new_fds) == 0) {
+ FD_CLR(current, readfds);
+ }
+ } else {
+ if (FD_ISSET(current, readfds) && FD_ISSET(current, &new_fds)
+ && FD_ISSET(shadow_fd, &new_fds)) {
+ ret -= 1;
+ }
+ if (FD_ISSET(current, readfds) &&
+ FD_ISSET(current, &new_fds) == 0 &&
+ FD_ISSET(shadow_fd, &new_fds) == 0) {
+ FD_CLR(current, readfds);
+ }
+ }
+ }
+ }
+
+done:
+
+ __sdp_log(2, "SELECT: <%s:%d> return <%d>\n",
+ program_invocation_short_name, n, ret);
+ return ret;
+} /* select */
+
+/* ========================================================================= */
+/*..pselect -- replacement socket call. */
+/*
+ if we have shadow we must pselect on it too - which requires a hack back
+ and forth
+*/
+int
+pselect(int n,
+ fd_set * readfds,
+ fd_set * writefds,
+ fd_set * exceptfds,
+ const struct timespec *timeout, const sigset_t * sigmask)
+{
+ int shadow_fd;
+ int ret;
+ int current;
+ int maxi = 0;
+ fd_set new_fds;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.pselect) {
+ __sdp_log(9, "Error pselect: no implementation for pselect found\n");
+ return -1;
+ }
+
+ __sdp_log(2, "PSELECT: <%s:%d>\n", program_invocation_short_name, n);
+
+ /* if we do not read - nothing to do */
+ if (readfds == NULL) {
+ ret =
+ _socket_funcs.pselect(n, readfds, writefds, exceptfds, timeout,
+ sigmask);
+ goto done;
+ }
+
+ FD_ZERO(&new_fds);
+ if (n > 0) {
+ maxi = n - 1;
+ }
+
+ /* add shadow bits */
+ for (current = 0; current < n; current++) {
+ if (FD_ISSET(current, readfds)) {
+ FD_SET(current, &new_fds);
+ if (current > maxi) {
+ maxi = current;
+ }
+ shadow_fd = get_shadow_fd_by_fd(current);
+ if (shadow_fd != -1) {
+ __sdp_log(1,
+ "PSELECT: adding fd:<%d> shadow_fd:<%d> to readfs\n",
+ current, shadow_fd);
+ FD_SET(shadow_fd, &new_fds);
+ if (shadow_fd > maxi) {
+ maxi = shadow_fd;
+ }
+ }
+ }
+ }
+
+ __sdp_log(1, "PSELECT: invoking pselect n=<%d>\n", 1 + maxi);
+ ret = _socket_funcs.pselect(1 + maxi,
+ &new_fds, writefds, exceptfds,
+ timeout, sigmask);
+
+ /* remove the count and bits of the shadows */
+ if (ret >= 0) {
+ for (current = 0; current < n; current++) {
+ shadow_fd = get_shadow_fd_by_fd(current);
+ if (shadow_fd == -1) {
+ if (FD_ISSET(current, readfds) &&
+ FD_ISSET(current, &new_fds) == 0) {
+ FD_CLR(current, readfds);
+ }
+ } else {
+ if (FD_ISSET(current, readfds) && FD_ISSET(current, &new_fds)
+ && FD_ISSET(shadow_fd, &new_fds)) {
+ ret -= 1;
+ }
+ if (FD_ISSET(current, readfds) &&
+ FD_ISSET(current, &new_fds) == 0 &&
+ FD_ISSET(shadow_fd, &new_fds) == 0) {
+ FD_CLR(current, readfds);
+ }
+ }
+ }
+ }
+
+done:
+
+ __sdp_log(2, "PSELECT: <%s:%d> return <%d>\n",
+ program_invocation_short_name, n, ret);
+ return ret;
+} /* pselect */
+
+/* ========================================================================= */
+/*..poll -- replacement socket call. */
+/*
+ if we have shadow we must poll on it too - which requires a hack back
+ and forth
+*/
+int poll(struct pollfd *ufds, nfds_t nfds, int timeout)
+{
+ int ret;
+ int shadow_fd;
+ int current;
+ int extra = 0;
+ struct pollfd *poll_fds = NULL;
+ struct pollfd *poll_fd_ptr = NULL;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.poll) {
+ __sdp_log(9, "Error poll: no implementation for poll found\n");
+ return -1;
+ }
+
+ __sdp_log(2, "POLL: <%s:%d>\n", program_invocation_short_name, nfds);
+
+ /* if we do not have any file desc - nothing to do */
+ if (ufds == NULL) {
+ ret = _socket_funcs.poll(ufds, nfds, timeout);
+ goto done;
+ }
+
+ /* scan for how many extra fds are required */
+ for (current = 0; current < nfds; current++) {
+ shadow_fd = get_shadow_fd_by_fd(ufds[current].fd);
+ if (shadow_fd != -1)
+ extra++;
+ }
+
+ if (!extra) {
+ poll_fds = ufds;
+ } else {
+ poll_fds =
+ (struct pollfd *) malloc((nfds + extra) * sizeof(struct pollfd));
+ if (!poll_fds) {
+ __sdp_log(9,
+ "Error poll: malloc of extended pollfd array failed\n");
+ ret = -1;
+ errno = ENOMEM;
+ goto done;
+ }
+ poll_fd_ptr = poll_fds;
+ for (current = 0; current < nfds; current++) {
+ *poll_fd_ptr = ufds[current];
+ poll_fd_ptr++;
+ shadow_fd = get_shadow_fd_by_fd(ufds[current].fd);
+ if (shadow_fd != -1) {
+ __sdp_log(1, "POLL: adding fd:<%d> shadow_fd:<%d> to readfs\n",
+ current, shadow_fd);
+ *poll_fd_ptr = ufds[current];
+ poll_fd_ptr->fd = shadow_fd;
+ poll_fd_ptr++;
+ }
+ }
+ }
+
+ __sdp_log(1, "POLL: invoking poll nfds=<%d>\n", nfds + extra);
+ ret = _socket_funcs.poll(poll_fds, nfds + extra, timeout);
+
+ /* refactor into original list if any events */
+ if ((ret > 0) && extra) {
+ poll_fd_ptr = poll_fds;
+ for (current = 0; current < nfds; current++) {
+ shadow_fd = get_shadow_fd_by_fd(ufds[current].fd);
+ if (shadow_fd == -1) {
+ ufds[current] = *poll_fd_ptr;
+ } else {
+ ufds[current] = *poll_fd_ptr;
+ poll_fd_ptr++;
+ if (poll_fd_ptr->revents) {
+ if (ufds[current].revents)
+ ret--;
+ ufds[current].revents |= poll_fd_ptr->revents;
+ }
+ }
+ poll_fd_ptr++;
+ }
+ }
+
+ if (extra)
+ free(poll_fds);
+done:
+
+ __sdp_log(2, "POLL: <%s:%d> return <%d>\n",
+ program_invocation_short_name, nfds, ret);
+ return ret;
+} /* poll */
+
+#ifdef __linux__
+/* ========================================================================= */
+/*..epoll_create -- replacement socket call. */
+/*
+ Need to make the size twice as large for shadow fds
+*/
+int epoll_create(int size)
+{
+ int epfd;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.epoll_create) {
+ __sdp_log(9,
+ "Error epoll_create: no implementation for epoll_create found\n");
+ return -1;
+ }
+
+ __sdp_log(2, "EPOLL_CREATE: <%s:%d>\n", program_invocation_short_name,
+ size);
+
+ epfd = _socket_funcs.epoll_create(size * 2);
+
+ __sdp_log(2, "EPOLL_CREATE: <%s:%d> return %d\n",
+ program_invocation_short_name, size, epfd);
+ return epfd;
+} /* epoll_create */
+
+/* ========================================================================= */
+/*..epoll_ctl -- replacement socket call. */
+/*
+ Need to add/delete/modify shadow fds as well
+*/
+int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
+{
+ int ret, shadow_fd, ret2;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.epoll_ctl) {
+ __sdp_log(9,
+ "Error epoll_ctl: no implementation for epoll_ctl found\n");
+ return -1;
+ }
+
+ __sdp_log(2, "EPOLL_CTL: <%s:%d> op <%d:%d>\n",
+ program_invocation_short_name, epfd, op, fd);
+
+ ret = _socket_funcs.epoll_ctl(epfd, op, fd, event);
+
+ shadow_fd = get_shadow_fd_by_fd(fd);
+ if (shadow_fd != -1) {
+ ret2 = _socket_funcs.epoll_ctl(epfd, op, shadow_fd, event);
+ if (ret2 < 0) {
+ __sdp_log(9, "Error epoll_ctl <%s:%d:%d>",
+ program_invocation_short_name, fd, shadow_fd);
+ return ret2;
+ }
+ }
+
+ __sdp_log(2, "EPOLL_CTL: <%s:%d> return <%d>\n",
+ program_invocation_short_name, epfd, ret);
+ return ret;
+} /* epoll_ctl */
+
+/* ========================================================================= */
+/*..epoll_wait -- replacement socket call. */
+/*
+ We don't care who generated the event because all we get is user-context
+ values.
+*/
+int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
+{
+ int ret;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.epoll_wait) {
+ __sdp_log(9,
+ "Error epoll_wait: no implementation for epoll_wait found\n");
+ return -1;
+ }
+
+ __sdp_log(2, "EPOLL_WAIT: <%s:%d>\n", program_invocation_short_name, epfd);
+
+ ret = _socket_funcs.epoll_wait(epfd, events, maxevents, timeout);
+
+ __sdp_log(2, "EPOLL_WAIT: <%s:%d> return <%d>\n",
+ program_invocation_short_name, epfd, ret);
+ return ret;
+} /* epoll_wait */
+
+/* ========================================================================= */
+/*..epoll_pwait -- replacement socket call. */
+/*
+ We don't care who generated the event because all we get is user-context
+ values.
+*/
+int
+epoll_pwait(int epfd,
+ struct epoll_event *events,
+ int maxevents, int timeout, const sigset_t * sigmask)
+{
+ int ret;
+
+ if (init_status == 0)
+ __sdp_init();
+
+ if (NULL == _socket_funcs.epoll_pwait) {
+ __sdp_log(9,
+ "Error epoll_pwait: no implementation for epoll_pwait found\n");
+ return -1;
+ }
+
+ __sdp_log(2, "EPOLL_PWAIT: <%s:%d>\n", program_invocation_short_name, epfd);
+
+ ret = _socket_funcs.epoll_pwait(epfd, events, maxevents, timeout, sigmask);
+
+ __sdp_log(2, "EPOLL_PWAIT: <%s:%d> return <%d>\n",
+ program_invocation_short_name, epfd, ret);
+ return ret;
+} /* epoll_pwait */
+#endif
+
+/* ========================================================================= */
+
+/* --------------------------------------------------------------------- */
+/* */
+/* Library load/unload initialization/cleanup */
+/* */
+/* --------------------------------------------------------------------- */
+/* ========================================================================= */
+/*..__sdp_init -- intialize the library */
+void __sdp_init(void)
+{
+ char *config_file, *error_str;
+ int fd;
+ struct rlimit nofiles_limit;
+
+ /* HACK: races might apply here: can we assume init is happening
+ only within one thread ? */
+ if (init_status != 0)
+ return;
+ init_status = 1;
+
+ dev_null_fd = open("/dev/null", O_WRONLY);
+
+ /* figure out the max number of file descriptors */
+ if (getrlimit(RLIMIT_NOFILE, &nofiles_limit))
+ max_file_descriptors = 1024;
+ else
+ max_file_descriptors = nofiles_limit.rlim_cur;
+
+ /* allocate and initialize the shadow sdp sockets array */
+ libsdp_fd_attributes =
+ (struct sdp_extra_fd_attributes *) calloc(max_file_descriptors,
+ sizeof(struct
+ sdp_extra_fd_attributes));
+ for (fd = 0; fd < max_file_descriptors; fd++)
+ init_extra_attribute(fd);
+
+#ifndef RTLD_NEXT
+ /*
+ * open libc for original socket call.
+ * Solaris relies on RTLD next - since the socket calls are
+ * actually in libsocket rather than libc.
+ */
+ __libc_dl_handle = dlopen("/lib64/libc.so.6", RTLD_LAZY);
+ if (NULL == __libc_dl_handle) {
+ __libc_dl_handle = dlopen("/lib/libc.so.6", RTLD_LAZY);
+ if (NULL == __libc_dl_handle) {
+ fprintf(stderr, "%s\n", dlerror());
+ return;
+ }
+ }
+#endif
+
+ /*
+ * Get the original functions
+ */
+ _socket_funcs.ioctl = dlsym(__libc_dl_handle, "ioctl");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.fcntl = dlsym(__libc_dl_handle, "fcntl");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.socket = dlsym(__libc_dl_handle, "socket");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.setsockopt = dlsym(__libc_dl_handle, "setsockopt");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.connect = dlsym(__libc_dl_handle, "connect");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.listen = dlsym(__libc_dl_handle, "listen");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.bind = dlsym(__libc_dl_handle, "bind");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.close = dlsym(__libc_dl_handle, "close");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.dup = dlsym(__libc_dl_handle, "dup");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.dup2 = dlsym(__libc_dl_handle, "dup2");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.getpeername = dlsym(__libc_dl_handle, "getpeername");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.getsockname = dlsym(__libc_dl_handle, "getsockname");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.accept = dlsym(__libc_dl_handle, "accept");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.select = dlsym(__libc_dl_handle, "select");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.pselect = dlsym(__libc_dl_handle, "pselect");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.poll = dlsym(__libc_dl_handle, "poll");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+#ifdef __linux__
+ _socket_funcs.epoll_create = dlsym(__libc_dl_handle, "epoll_create");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.epoll_ctl = dlsym(__libc_dl_handle, "epoll_ctl");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.epoll_wait = dlsym(__libc_dl_handle, "epoll_wait");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_funcs.epoll_pwait = dlsym(__libc_dl_handle, "epoll_pwait");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+#endif
+#ifdef SOLARIS_BUILD
+ _socket_xnet_funcs.socket = dlsym(__libc_dl_handle, "__xnet_socket");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_xnet_funcs.connect = dlsym(__libc_dl_handle, "__xnet_connect");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_xnet_funcs.listen = dlsym(__libc_dl_handle, "__xnet_listen");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ _socket_xnet_funcs.bind = dlsym(__libc_dl_handle, "__xnet_bind");
+ if (NULL != (error_str = dlerror())) {
+ fprintf(stderr, "%s\n", error_str);
+ }
+
+ /* Determine program name by asking libdl */
+ Dl_argsinfo args_info;
+ if (NULL != dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args_info)) {
+ fprintf(stderr, "args_info: %s\n", dlerror());
+ } else {
+ program_invocation_name = args_info.dla_argv[0];
+ program_invocation_short_name = basename(args_info.dla_argv[0]);
+ }
+#endif
+
+ if (getenv("SIMPLE_LIBSDP") != NULL) {
+ simple_sdp_library = 1;
+ }
+
+ if (getenv("ALWAYS_USE_SDP") != NULL) {
+ simple_sdp_library = 1;
+ }
+#define LIBSDP_DEFAULT_CONFIG_FILE SYSCONFDIR "/libsdp.conf"
+ if (!simple_sdp_library) {
+ config_file = getenv("LIBSDP_CONFIG_FILE");
+ if (!config_file)
+ config_file = LIBSDP_DEFAULT_CONFIG_FILE;
+
+ if (__sdp_parse_config(config_file)) {
+ fprintf(stderr,
+ "libsdp Error: failed to parse config file:%s. Using defaults.\n",
+ config_file);
+ }
+ }
+
+ __sdp_log(1, "Max file descriptors:%d\n", max_file_descriptors);
+ init_status = 2;
+
+} /* __sdp_init */
+
+/* ========================================================================= */
+/*..__sdp_fini -- when the library is unloaded this is called */
+void __sdp_fini(void)
+{
+ struct use_family_rule *rule;
+ for (rule = __sdp_clients_family_rules_head; rule != NULL;
+ rule = rule->next)
+ free(rule->prog_name_expr);
+ for (rule = __sdp_servers_family_rules_head; rule != NULL;
+ rule = rule->next)
+ free(rule->prog_name_expr);
+
+ free(libsdp_fd_attributes);
+
+#ifndef RTLD_NEXT
+ dlclose(__libc_dl_handle);
+#endif
+} /* _fini */
diff --git a/contrib/ofed/libsdp/src/socket.c b/contrib/ofed/libsdp/src/socket.c
new file mode 100644
index 0000000..d40265b
--- /dev/null
+++ b/contrib/ofed/libsdp/src/socket.c
@@ -0,0 +1,167 @@
+/*
+ This software is available to you under a choice of one of two
+ licenses. You may choose to be licensed under the terms of the GNU
+ General Public License (GPL) Version 2, available at
+ <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD
+ license, available in the LICENSE.TXT file accompanying this
+ software. These details are also available at
+ <http://openib.org/license.html>.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ Copyright (c) 2004 Topspin Communications. All rights reserved.
+ Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
+
+ $Id$
+*/
+
+/*
+ * system includes
+ */
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+/*
+ For non-i386 systems, we pass socket() through to library code using
+ dlsym() instead of trying to make the system call directly. This
+ may cause problems if this library is LD_PRELOADed before the real C
+ library is available. Eventually we may want to add the same type
+ of system call assembly code as i386 has for IA64 and AMD64, but for
+ now....
+*/
+#ifndef i386
+#define _GNU_SOURCE /* Get RTLD_NEXT */
+#include <dlfcn.h>
+#else
+#include <sys/syscall.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <string.h>
+/*
+ * SDP specific includes
+ */
+#include "linux/sdp_inet.h"
+
+#if 0
+#define _SDP_VERBOSE_PRELOAD
+#endif
+
+#define SOCKOP_socket 1
+#define SOCKOP_bind 2
+#define SOCKOP_connect 3
+#define SOCKOP_listen 4
+#define SOCKOP_accept 5
+#define SOCKOP_getsockname 6
+#define SOCKOP_getpeername 7
+#define SOCKOP_socketpair 8
+#define SOCKOP_send 9
+#define SOCKOP_recv 10
+#define SOCKOP_sendto 11
+#define SOCKOP_recvfrom 12
+#define SOCKOP_shutdown 13
+#define SOCKOP_setsockopt 14
+#define SOCKOP_getsockopt 15
+#define SOCKOP_sendmsg 16
+#define SOCKOP_recvmsg 17
+
+extern char * program_invocation_name;
+extern char * program_invocation_short_name;
+extern char ** const environ;
+
+/* ========================================================================= */
+/*..socket -- replacment socket call. */
+int socket
+(
+ int domain,
+ int type,
+ int protocol
+)
+{
+#ifdef i386
+ long __ret;
+ void *__scratch;
+ int call[3];
+#endif
+ char *test;
+ char *inet;
+ char **tenviron;
+
+#ifdef _SDP_VERBOSE_PRELOAD
+ FILE *fd;
+#endif
+ /*
+ * check for magic enviroment variable
+ */
+ if ((AF_INET == domain || AF_INET6 == domain) &&
+ SOCK_STREAM == type) {
+
+ if (environ) {
+ tenviron = environ;
+ for (test = *tenviron; NULL != test; test = *++tenviron) {
+
+ inet = AF_INET_STR;
+
+ while (*inet == *test && '\0' != *inet) {
+
+ inet++;
+ test++;
+ } /* while */
+
+ if ('\0' == *inet && '=' == *test) {
+
+ domain = AF_INET_SDP;
+ break;
+ } /* if */
+ } /* for */
+ } /* if */
+ } /* if */
+
+#ifdef _SDP_VERBOSE_PRELOAD
+ fd = fopen("/tmp/libsdp.log.txt", "a+");
+
+ fprintf(fd, "SOCKET: <%s> domain <%d> type <%d> protocol <%d>\n",
+ program_invocation_short_name, domain, type, protocol);
+
+ fclose(fd);
+#endif
+
+#ifdef i386
+ /* Make the socket() system call directly, as described above */
+ call[0] = domain;
+ call[1] = type;
+ call[2] = protocol;
+
+ __asm__ __volatile__("movl %%ebx, %1\n" /* save %ebx */
+ "movl %3, %%ebx\n" /* put sockopt in %ebx as arg */
+ "int $0x80\n" /* do syscall */
+ "movl %1, %%ebx\n" /* restore %ebx */
+ : "=a" (__ret), "=r" (__scratch)
+ : "0" (__NR_socketcall),
+ "g" (SOCKOP_socket),
+ "c" (call));
+ return __ret;
+#else /* i386 */
+ /* Use the standard library socket() to pass through the call */
+ {
+ static int (*orig_socket)(int, int, int);
+
+ if (!orig_socket) {
+ orig_socket = dlsym(RTLD_NEXT, "socket");
+ }
+
+ return orig_socket(domain, type, protocol);
+ }
+#endif /* i386 */
+} /* socket */
OpenPOWER on IntegriCloud