Index: head/contrib/ofed/libsdp/ChangeLog =================================================================== --- head/contrib/ofed/libsdp/ChangeLog (revision 296401) +++ head/contrib/ofed/libsdp/ChangeLog (revision 296402) @@ -1,96 +1,117 @@ +2011-04-28 10:25:22 +0300 Amir Vadai + * 8cc6058 libsdp: Use logroate on /var/log/libsdp.log + +2011-01-17 15:44:30 +0200 Amir Vadai + * d7fdb72 libsdp: removed a debug print + +2011-01-12 11:24:57 +0200 Amir Vadai + * 63e0cf1 libsdp: recompiled yacc files + +2011-01-10 17:29:14 +0200 Amir Vadai + * 54de044 libsdp: Add IPv6 support to configuration file + +2011-01-05 09:52:05 +0200 Amir Vadai + * e57ee9c libsdp: Do not set-user-ID on default. + +2011-01-03 11:33:44 +0200 Amir Vadai + * 18447bb libsdp: Do not block other socket types + +2011-01-02 12:29:13 +0200 Amir Vadai + * e9d2c10 libsdp: Fix bad errno value + 2010-12-26 18:14:02 +0200 Amir Vadai * 9c2ad15 libsdp: full ipv6 support 2010-11-29 11:43:51 +0200 Amir Vadai * 0a3d5c3 libsdp: BUG2130 - libsdp.so is not installed + version 1.1.106 2010-11-08 14:41:27 +0200 Amir Vadai * 7a1880f libsdp: updated version to 1.1.105 2010-11-08 14:31:13 +0200 Amir Vadai * c6efc06 libsdp: fix security issues with log file 2010-11-02 15:28:06 +0200 Amir Vadai * 09343d1 libsdp: fix bad permissions 2010-10-28 13:46:39 +0200 root * 46d845d libsdp: fixed indentation 2010-10-04 11:49:46 +0200 Amir Vadai * 59b6a36 libsdp: updated version to 1.1.104 2010-10-04 11:22:23 +0200 Amir Vadai * 21b63e0 libsdp: fix libsdp.so permissions 2010-10-04 11:20:49 +0200 Amir Vadai * 3180e25 libsdp: fix "make dist" 2010-09-13 10:31:52 +0200 Amir Vadai * df744a5 libsdp: updated version to 1.1.103 2010-09-13 10:45:40 +0200 Amir Vadai * e3ce469 libsdp: don't make libsdp depend on sdp_socket.h from ib-kernel 2010-08-03 15:35:11 +0300 Amir Vadai * c5ff8e2 libsdp: updated version to 1.1.102 2010-08-03 15:33:57 +0300 Amir Vadai * 82fe3f9 libsdp: search openib headers according to 'prefix' 2010-04-11 11:38:47 +0300 Amir Vadai * 76060c5 libsdp: changed version to 1.1.101 2010-04-08 09:33:29 +0300 Eldad Zinger * 8bf57aa libsdp: added differentiation between bind failures of sdp. 2010-03-23 10:13:45 +0200 Eldad Zinger * 93706ed sdp: BUG1984 - fix for bad memory access. 2010-04-08 15:40:55 +0300 Amir Vadai * dadef4b libsdp: add path to openib include's 2010-02-18 11:04:29 +0200 Amir Vadai * 920ea31 libsdp: changed version to 1.1.100 2010-02-18 11:02:20 +0200 Amir Vadai * 0fe8a11 libsdp: updated changelog from git + script to get change log 2010-02-18 10:49:42 +0200 Amir Vadai * a298098 libsdp: Fix memory leak. free libsdp_fd_attributes 2010-02-18 10:49:00 +0200 Amir Vadai * cf4ceab libsdp: make libsdp.so have gid bit on 2008-11-26 13:44:26 +0200 Amir Vadai * b1eaecb libsdp: Enable building libsdp on Solaris 2008-11-23 Amir Vadai * BUG1405 - conflict when running an application that use yacc. 2008-12-08 18:29:09 +0200 Yossi Etigin * dcfca98 libsdp: BUG1256 - Add epoll support 2008-11-23 16:09:21 +0200 Amir Vadai * 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 * 81d6ec3 removed not unnecessary use of va_copy. 2008-06-12 14:13:07 +0300 Amir Vadai * 90f25b7 Fixed compilation error on Fedora Release 9 2006-05-29 Eitan Zahavi * 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 Index: head/contrib/ofed/libsdp/Makefile.am =================================================================== --- head/contrib/ofed/libsdp/Makefile.am (revision 296401) +++ head/contrib/ofed/libsdp/Makefile.am (revision 296402) @@ -1,23 +1,23 @@ SUBDIRS = src -EXTRA_DIST = libsdp.spec.in libsdp.conf +EXTRA_DIST = libsdp.spec.in libsdp.conf scripts/libsdp.logrotate 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 Index: head/contrib/ofed/libsdp/libsdp.conf =================================================================== --- head/contrib/ofed/libsdp/libsdp.conf (revision 296401) +++ head/contrib/ofed/libsdp/libsdp.conf (revision 296402) @@ -1,139 +1,145 @@ # 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./log # or /var/log/ 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 ] [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 - messages will be written to the file /var/log/ for root. # for regular user, if full path is requsted ./log # or /tmp/./log if no path is requested # Due to security reasons, 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 : # # 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. # # can be one of: # "server" or "listen" - for defining the listening port address family # "client" or "connect" - for defining the connected port address family # # 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. # # 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 = [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. +# [/]|* +# IP address = IPv4 in dotted-quad format, "ddd.ddd.ddd.ddd" or IPv6 network +# address in any allowed IPv6 address format. +# prefix_length = Number of bits to match. A prefix_length of 16 matches the +# subnet mask 255.255.0.0 in IPv4, or ffff::0 in IPv6. +# A prefix_length of 32 for IPv4 or 128 for IPv6 requires +# matching of the exact IP. # # 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 clients connecting to machines that belongs to subnet 1234:5678::* +# family role program address:port[-range] +# use sdp connect * 1234:5678::0/64:* # # 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 # ############################################################################## Index: head/contrib/ofed/libsdp/libsdp.spec.in =================================================================== --- head/contrib/ofed/libsdp/libsdp.spec.in (revision 296401) +++ head/contrib/ofed/libsdp/libsdp.spec.in (revision 296402) @@ -1,55 +1,61 @@ 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} +Requires: %{name} = %{version}-%{release}, logrotate %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 +etc=$RPM_BUILD_ROOT%{_sysconfdir} make DESTDIR=${RPM_BUILD_ROOT} install # remove unpackaged files from the buildroot rm -f $RPM_BUILD_ROOT%{_libdir}/*.la +mkdir -p $etc/logrotate.d +install -m 644 scripts/libsdp.logrotate $etc/logrotate.d/libsdp %clean rm -rf $RPM_BUILD_ROOT %files -%defattr(6644,root,root) +# For set-user-ID/set-group-ID ELF binaries, only libraries in the standard search directories that are also set-user-ID +# To do so, change line below to: %defattr(6644,root,root) +%defattr(0644,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 +%config(noreplace) %{_sysconfdir}/logrotate.d/libsdp %files devel -%defattr(6644,root,root,-) +%defattr(0644,root,root,-) %{_libdir}/libsdp*.so %changelog * Sun Jul 22 2007 Vladimir Sokolovsky - Initial packaging Index: head/contrib/ofed/libsdp/scripts/libsdp.logrotate =================================================================== --- head/contrib/ofed/libsdp/scripts/libsdp.logrotate (nonexistent) +++ head/contrib/ofed/libsdp/scripts/libsdp.logrotate (revision 296402) @@ -0,0 +1,6 @@ +/var/log/libsdp.log { + missingok + notifempty + copytruncate + compress +} Index: head/contrib/ofed/libsdp/src/config_parser.c =================================================================== --- head/contrib/ofed/libsdp/src/config_parser.c (revision 296401) +++ head/contrib/ofed/libsdp/src/config_parser.c (revision 296402) @@ -1,1890 +1,1908 @@ /* 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 + LINE = 272, + SUBNET = 273 }; #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 +#define SUBNET 273 /* Copy the first part of user declarations. */ #line 39 "./config_parser.y" /* header section */ #include #include #include #include "libsdp.h" #include #include #include #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) +static void __sdp_set_ip_addr(char *addr) { - 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"); - } + int rc; + char *addrlen; + struct sockaddr_in *addr4 = (struct sockaddr_in *)(&__sdp_rule.ip); + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)(&__sdp_rule.ip); + int prefixlen = 0; + + addrlen = strrchr(addr, '/'); + if (addrlen) { + prefixlen = atoi(addrlen + 1); + *addrlen = '\0'; + } + + rc = inet_pton(AF_INET, addr, &addr4->sin_addr); + if (rc > 0) { + addr4->sin_family = AF_INET; + __sdp_rule.prefixlen = prefixlen ?: 32; + return; + } + + rc = inet_pton(AF_INET6, addr, &addr6->sin6_addr); + if (rc > 0) { + addr6->sin6_family = AF_INET6; + __sdp_rule.prefixlen = prefixlen ?: 128; + return; + } + + parse_err = 1; + yyerror("provided address is not legal"); } +static const char *addr2str(struct sockaddr_storage *src) +{ + static char dst[INET6_ADDRSTRLEN]; + int af = src->ss_family; + const struct sockaddr_in *addr4 = (const struct sockaddr_in *)src; + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)src; + + if (af == AF_INET6) + return inet_ntop(af, &addr6->sin6_addr, dst, INET6_ADDRSTRLEN); + + return inet_ntop(af, &addr4->sin_addr, dst, INET6_ADDRSTRLEN); +} + 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 )); + addr2str(&__sdp_rule.ip), __sdp_rule.prefixlen); } 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" +#line 197 "./config_parser.y" { int ival; char *sval; } /* Line 193 of yacc.c. */ -#line 270 "y.tab.c" +#line 302 "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" +#line 223 "./config_parser.y" long __sdp_config_line_num; /* Line 216 of yacc.c. */ -#line 286 "y.tab.c" +#line 318 "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 /* 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 /* 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 /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* 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 /* 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 /* 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 +#define YYLAST 31 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 23 +#define YYNTOKENS 22 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 17 +#define YYNNTS 16 /* YYNRULES -- Number of rules. */ -#define YYNRULES 33 +#define YYNRULES 31 /* YYNRULES -- Number of states. */ -#define YYNSTATES 53 +#define YYNSTATES 44 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 272 +#define YYMAXUTOK 273 #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, 20, 2, 2, 21, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 19, 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 + 15, 16, 17, 18 }; #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 + 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, + 75, 79 }; /* 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 + 25, 0, -1, 17, -1, 23, 17, -1, -1, 23, + -1, 24, 26, -1, -1, 26, 27, -1, 28, -1, + 32, -1, 10, 29, 23, -1, -1, 29, 30, -1, + 29, 31, -1, 11, 12, -1, 11, 13, -1, 11, + 14, 15, -1, 16, 9, -1, 3, 33, 34, 35, + 36, 19, 37, 23, -1, 6, -1, 7, -1, 8, + -1, 5, -1, 4, -1, 15, -1, 20, -1, 18, + -1, 20, -1, 9, -1, 9, 21, 9, -1, 20, + -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 + 0, 229, 229, 230, 232, 233, 236, 239, 240, 244, + 245, 249, 252, 253, 254, 258, 259, 260, 264, 268, + 272, 273, 274, 278, 279, 283, 284, 288, 289, 293, + 294, 295 }; #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", + "\"new line\"", "\"ip address\"", "':'", "'*'", "'-'", "$accept", "NL", "ONL", "config", "statements", "statement", "log_statement", "log_opts", "log_dest", "verbosity", "socket_statement", "family", "role", "program", - "address", "ipv4", "ports", 0 + "address", "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 + 265, 266, 267, 268, 269, 270, 271, 272, 273, 58, + 42, 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 + 0, 22, 23, 23, 24, 24, 25, 26, 26, 27, + 27, 28, 29, 29, 29, 30, 30, 30, 31, 32, + 33, 33, 33, 34, 34, 35, 35, 36, 36, 37, + 37, 37 }; /* 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 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 + 16, 0, 18, 27, 28, 0, 17, 0, 29, 31, + 0, 0, 19, 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 + 12, 16, 20, 28, 35, 40 }; /* 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 + -10, -18, 5, -18, 21, -18, -1, -18, 7, -18, + -18, -18, -18, -18, -18, -18, 15, -6, -18, -18, + -12, 4, 16, 5, -18, -18, -18, -18, -14, -18, + -18, 9, -18, -18, -18, 8, -18, -8, 10, -18, + -10, 17, 5, -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 + -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 + 23, 38, 8, 26, 33, 21, 34, 1, 27, 9, + 22, 1, 39, 13, 14, 15, 29, 30, 31, 18, + 19, 7, 5, 42, 36, 32, 43, 37, 0, 0, + 0, 41 }; -static const yytype_uint8 yycheck[] = +static const yytype_int8 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 + 17, 9, 3, 15, 18, 11, 20, 17, 20, 10, + 16, 17, 20, 6, 7, 8, 12, 13, 14, 4, + 5, 0, 17, 40, 15, 9, 9, 19, -1, -1, + -1, 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 + 0, 17, 23, 24, 25, 17, 26, 0, 3, 10, + 27, 28, 32, 6, 7, 8, 33, 29, 4, 5, + 34, 11, 16, 23, 30, 31, 15, 20, 35, 12, + 13, 14, 9, 18, 20, 36, 15, 19, 9, 20, + 37, 21, 23, 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 /* 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" +#line 258 "./config_parser.y" { __sdp_log_set_log_stderr(); } break; case 16: -#line 228 "./config_parser.y" +#line 259 "./config_parser.y" { __sdp_log_set_log_syslog(); } break; case 17: -#line 229 "./config_parser.y" +#line 260 "./config_parser.y" { __sdp_log_set_log_file((yyvsp[(3) - (3)].sval)); } break; case 18: -#line 233 "./config_parser.y" +#line 264 "./config_parser.y" { __sdp_log_set_min_level((yyvsp[(2) - (2)].ival)); } break; case 19: -#line 237 "./config_parser.y" +#line 268 "./config_parser.y" { __sdp_add_rule(); } break; case 20: -#line 241 "./config_parser.y" +#line 272 "./config_parser.y" { __sdp_rule.target_family = USE_TCP; } break; case 21: -#line 242 "./config_parser.y" +#line 273 "./config_parser.y" { __sdp_rule.target_family = USE_SDP; } break; case 22: -#line 243 "./config_parser.y" +#line 274 "./config_parser.y" { __sdp_rule.target_family = USE_BOTH; } break; case 23: -#line 247 "./config_parser.y" +#line 278 "./config_parser.y" { current_role = 1; } break; case 24: -#line 248 "./config_parser.y" +#line 279 "./config_parser.y" { current_role = 2; } break; case 25: -#line 252 "./config_parser.y" +#line 283 "./config_parser.y" { __sdp_set_prog_name_expr((yyvsp[(1) - (1)].sval)); } break; case 26: -#line 253 "./config_parser.y" +#line 284 "./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; } +#line 288 "./config_parser.y" + { __sdp_rule.match_by_addr = 1; __sdp_set_ip_addr((yyvsp[(1) - (1)].sval)); } 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" +#line 289 "./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" + case 29: +#line 293 "./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" + case 30: +#line 294 "./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" + case 31: +#line 295 "./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" +#line 1632 "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" +#line 298 "./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 #include /* 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); } Index: head/contrib/ofed/libsdp/src/config_parser.h =================================================================== --- head/contrib/ofed/libsdp/src/config_parser.h (revision 296401) +++ head/contrib/ofed/libsdp/src/config_parser.h (revision 296402) @@ -1,95 +1,97 @@ /* 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 + LINE = 272, + SUBNET = 273 }; #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 +#define SUBNET 273 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 167 "./config_parser.y" +#line 197 "./config_parser.y" { int ival; char *sval; } /* Line 1529 of yacc.c. */ -#line 88 "y.tab.h" +#line 90 "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; Index: head/contrib/ofed/libsdp/src/config_parser.y =================================================================== --- head/contrib/ofed/libsdp/src/config_parser.y (nonexistent) +++ head/contrib/ofed/libsdp/src/config_parser.y (revision 296402) @@ -0,0 +1,359 @@ +/* + * 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: config_parser.y 1.5 2005/06/29 11:39:27 eitan Exp $ + */ + + +/* + +*/ +%{ + +/* header section */ +#include +#include +#include +#include "libsdp.h" +#include +#include +#include + +#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) ); +} + +static void __sdp_set_ip_addr(char *addr) +{ + int rc; + char *addrlen; + struct sockaddr_in *addr4 = (struct sockaddr_in *)(&__sdp_rule.ip); + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)(&__sdp_rule.ip); + int prefixlen = 0; + + addrlen = strrchr(addr, '/'); + if (addrlen) { + prefixlen = atoi(addrlen + 1); + *addrlen = '\0'; + } + + rc = inet_pton(AF_INET, addr, &addr4->sin_addr); + if (rc > 0) { + addr4->sin_family = AF_INET; + __sdp_rule.prefixlen = prefixlen ?: 32; + return; + } + + rc = inet_pton(AF_INET6, addr, &addr6->sin6_addr); + if (rc > 0) { + addr6->sin6_family = AF_INET6; + __sdp_rule.prefixlen = prefixlen ?: 128; + return; + } + + parse_err = 1; + yyerror("provided address is not legal"); +} + +static const char *addr2str(struct sockaddr_storage *src) +{ + static char dst[INET6_ADDRSTRLEN]; + int af = src->ss_family; + const struct sockaddr_in *addr4 = (const struct sockaddr_in *)src; + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)src; + + if (af == AF_INET6) + return inet_ntop(af, &addr6->sin6_addr, dst, INET6_ADDRSTRLEN); + + return inet_ntop(af, &addr4->sin_addr, dst, INET6_ADDRSTRLEN); +} + +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) { + sprintf(buf+strlen(buf), " %s/%d", + addr2str(&__sdp_rule.ip), __sdp_rule.prefixlen); + } 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; +} + +%} + + +%union { + int ival; + char *sval; +} +%token USE "use" +%token CLIENT "client or connect" +%token SERVER "server or listen" +%token TCP "tcp" +%token SDP "sdp" +%token BOTH "both" +%token INT "integer value" +%token LOG "log statement" +%token DEST "destination" +%token STDERR "stderr" +%token SYSLOG "syslog" +%token FILENAME "file" +%token NAME "a name" +%token LEVEL "min-level" +%token LINE "new line" +%token SUBNET "ip address" +%type NAME SUBNET +%type INT LOG DEST STDERR SYSLOG FILENAME USE TCP SDP BOTH CLIENT SERVER LEVEL LINE +%debug +%error-verbose +%start config + +%{ + long __sdp_config_line_num; +%} +%% + +NL: + LINE + | NL LINE; + +ONL: + | NL; + +config: + ONL statements + ; + +statements: + | statements statement + ; + +statement: + log_statement + | socket_statement + ; + +log_statement: + LOG log_opts NL + ; + +log_opts: + | log_opts log_dest + | log_opts verbosity + ; + +log_dest: + DEST STDERR { __sdp_log_set_log_stderr(); } + | DEST SYSLOG { __sdp_log_set_log_syslog(); } + | DEST FILENAME NAME { __sdp_log_set_log_file($3); } + ; + +verbosity: + LEVEL INT { __sdp_log_set_min_level($2); } + ; + +socket_statement: + USE family role program address ':' ports NL { __sdp_add_rule(); } + ; + +family: + TCP { __sdp_rule.target_family = USE_TCP; } + | SDP { __sdp_rule.target_family = USE_SDP; } + | BOTH { __sdp_rule.target_family = USE_BOTH; } + ; + +role: + SERVER { current_role = 1; } + | CLIENT { current_role = 2; } + ; + +program: + NAME { __sdp_set_prog_name_expr($1); } + | '*' { __sdp_set_prog_name_expr("*"); } + ; + +address: + SUBNET { __sdp_rule.match_by_addr = 1; __sdp_set_ip_addr($1); } + | '*' { __sdp_rule.match_by_addr = 0; __sdp_rule.prefixlen = 32; } + ; + +ports: + INT { __sdp_rule.match_by_port = 1; __sdp_rule.sport= $1; __sdp_rule.eport= $1; } + | INT '-' INT { __sdp_rule.match_by_port = 1; __sdp_rule.sport= $1; __sdp_rule.eport= $3; } + | '*' { __sdp_rule.match_by_port = 0; __sdp_rule.sport= 0 ; __sdp_rule.eport= 0; } + ; + +%% + +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 +#include + +/* 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); +} + + Index: head/contrib/ofed/libsdp/src/config_scanner.c =================================================================== --- head/contrib/ofed/libsdp/src/config_scanner.c (revision 296401) +++ head/contrib/ofed/libsdp/src/config_scanner.c (revision 296402) @@ -1,1885 +1,1932 @@ #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 #include /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ #ifdef c_plusplus #ifndef __cplusplus #define __cplusplus #endif #endif #ifdef __cplusplus #include /* 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 #include #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] = +#define YY_NUM_RULES 21 +#define YY_END_OF_BUFFER 22 +static yyconst short int yy_accept[195] = { 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, 22, 20, 19, 17, 18, 20, + 3, 3, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 19, 1, 16, 16, 16, 3, 3, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 1, 19, 18, 0, 0, 0, 0, 3, 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, + 0, 0, 0, 0, 19, 1, 1, 16, 16, 16, + 16, 16, 16, 3, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 4, - 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 + 0, 12, 0, 0, 0, 11, 10, 1, 16, 2, + 2, 16, 16, 16, 16, 16, 16, 4, 16, 12, + 16, 16, 16, 11, 10, 0, 13, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 16, 13, 16, 16, + 16, 9, 16, 16, 16, 16, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, + 16, 16, 16, 14, 0, 0, 15, 0, 7, 8, + 14, 16, 16, 15, 16, 7, 8, 0, 0, 16, + 16, 0, 0, 16, 16, 0, 6, 16, 6, 0, + 16, 5, 5, 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, 5, 1, 1, 6, 7, 8, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 11, 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, + 1, 1, 1, 1, 1, 1, 12, 13, 14, 15, - 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, + 16, 17, 18, 19, 20, 1, 1, 21, 22, 23, + 24, 25, 1, 26, 27, 28, 29, 30, 1, 1, + 31, 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] = +static yyconst int yy_meta[32] = { 0, - 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 1, 1, 1, 4, 1, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 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] = +static yyconst short int yy_base[202] = { 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, + 0, 30, 34, 64, 295, 296, 292, 296, 0, 60, + 62, 65, 68, 0, 269, 56, 276, 271, 58, 270, + 68, 275, 261, 83, 0, 0, 285, 93, 78, 82, + 275, 86, 87, 104, 105, 106, 98, 265, 104, 270, + 256, 280, 279, 0, 269, 0, 114, 128, 120, 271, + 250, 257, 253, 248, 253, 246, 254, 248, 245, 243, + 253, 240, 241, 249, 132, 0, 0, 0, 262, 0, + 132, 132, 139, 142, 252, 234, 241, 237, 146, 238, + 231, 239, 233, 230, 228, 238, 225, 226, 234, 247, + 136, 296, 0, 229, 231, 223, 217, 228, 215, 296, - 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 + 236, 296, 211, 224, 218, 296, 296, 0, 149, 0, + 153, 219, 221, 213, 207, 218, 205, 0, 226, 0, + 201, 214, 208, 0, 0, 157, 296, 205, 211, 206, + 296, 209, 203, 207, 196, 197, 160, 0, 197, 203, + 198, 0, 201, 195, 199, 188, 189, 184, 197, 187, + 186, 192, 181, 180, 187, 176, 189, 179, 178, 184, + 173, 172, 178, 296, 164, 176, 296, 154, 296, 296, + 0, 155, 168, 0, 146, 0, 0, 144, 155, 140, + 147, 136, 134, 111, 106, 77, 296, 64, 0, 58, + 49, 296, 0, 296, 173, 29, 177, 181, 185, 189, + + 193 } ; -static yyconst short int yy_def[177] = +static yyconst short int yy_def[202] = { 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, + 194, 1, 194, 3, 194, 194, 194, 194, 195, 196, + 196, 11, 11, 11, 11, 11, 11, 11, 194, 194, + 194, 194, 194, 194, 197, 198, 199, 198, 28, 28, + 28, 28, 28, 28, 28, 28, 198, 198, 198, 198, + 198, 200, 194, 195, 13, 11, 194, 13, 11, 11, + 194, 194, 194, 11, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 201, 197, 198, 199, 28, + 28, 198, 28, 28, 28, 198, 198, 198, 28, 198, + 198, 198, 198, 198, 198, 198, 198, 198, 198, 200, + 194, 194, 11, 194, 194, 194, 194, 194, 194, 194, - 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 + 194, 194, 194, 194, 194, 194, 194, 201, 198, 198, + 28, 198, 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 194, 194, 194, + 194, 194, 194, 194, 194, 198, 198, 198, 198, 198, + 198, 198, 198, 194, 194, 194, 194, 194, 194, 194, + 198, 198, 198, 198, 198, 198, 198, 194, 194, 198, + 198, 194, 194, 198, 198, 194, 194, 198, 198, 194, + 198, 194, 198, 0, 194, 194, 194, 194, 194, 194, + + 194 } ; -static yyconst short int yy_nxt[243] = +static yyconst short int yy_nxt[328] = { 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, + 6, 7, 8, 9, 6, 6, 10, 6, 11, 12, + 13, 14, 15, 16, 17, 14, 18, 6, 6, 6, + 19, 20, 6, 6, 6, 6, 21, 22, 23, 6, + 6, 24, 46, 25, 26, 7, 8, 27, 26, 26, + 28, 26, 29, 30, 31, 32, 33, 34, 35, 32, + 36, 26, 26, 26, 37, 38, 26, 26, 26, 26, + 39, 40, 41, 26, 26, 24, 45, 42, 45, 47, + 45, 193, 48, 49, 49, 194, 52, 56, 50, 53, + 192, 57, 59, 60, 65, 72, 66, 191, 73, 72, + 74, 74, 73, 72, 72, 61, 73, 73, 62, 70, - 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, + 190, 71, 71, 70, 71, 71, 71, 71, 71, 71, + 76, 72, 72, 72, 73, 73, 73, 81, 84, 85, + 79, 82, 91, 91, 77, 80, 189, 78, 49, 49, + 188, 86, 92, 65, 87, 66, 93, 93, 45, 72, + 109, 109, 73, 110, 91, 91, 126, 111, 111, 72, + 74, 74, 73, 72, 187, 186, 73, 109, 109, 137, + 72, 92, 185, 73, 110, 92, 92, 184, 110, 110, + 183, 182, 115, 44, 44, 181, 44, 67, 67, 180, + 67, 68, 171, 179, 68, 69, 69, 178, 69, 90, + 90, 164, 90, 108, 108, 177, 108, 176, 174, 175, - 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 + 174, 173, 172, 171, 170, 169, 167, 168, 167, 166, + 165, 164, 163, 162, 161, 160, 159, 158, 157, 156, + 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, + 145, 144, 143, 142, 141, 140, 139, 138, 136, 135, + 134, 133, 132, 131, 130, 129, 128, 127, 67, 125, + 124, 123, 122, 121, 120, 119, 118, 117, 116, 114, + 113, 112, 73, 44, 107, 106, 105, 104, 103, 102, + 101, 100, 99, 98, 97, 96, 95, 94, 194, 45, + 43, 67, 89, 88, 83, 75, 44, 64, 63, 58, + 55, 54, 51, 43, 194, 5, 194, 194, 194, 194, + + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194 } ; -static yyconst short int yy_chk[243] = +static yyconst short int yy_chk[328] = { 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, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 196, 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, 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, + 3, 3, 3, 3, 3, 4, 10, 4, 11, 11, + 10, 191, 11, 12, 12, 13, 16, 19, 13, 16, + 190, 19, 21, 21, 24, 29, 24, 188, 29, 30, + 30, 30, 30, 32, 33, 21, 32, 33, 21, 28, - 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, + 186, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 33, 34, 35, 36, 34, 35, 36, 37, 39, 39, + 35, 37, 47, 47, 34, 36, 185, 34, 49, 49, + 184, 39, 48, 65, 39, 65, 48, 48, 48, 71, + 72, 72, 71, 73, 91, 91, 91, 73, 73, 74, + 74, 74, 74, 79, 183, 182, 79, 109, 109, 109, + 111, 126, 181, 111, 137, 126, 126, 180, 137, 137, + 179, 178, 79, 195, 195, 175, 195, 197, 197, 173, + 197, 198, 172, 168, 198, 199, 199, 166, 199, 200, + 200, 165, 200, 201, 201, 163, 201, 162, 161, 160, - 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 + 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, + 149, 148, 147, 146, 145, 144, 143, 141, 140, 139, + 136, 135, 134, 133, 132, 130, 129, 128, 123, 122, + 121, 119, 117, 116, 115, 114, 113, 112, 105, 104, + 103, 101, 99, 98, 97, 96, 95, 94, 90, 89, + 88, 87, 86, 85, 84, 83, 82, 81, 80, 78, + 77, 76, 75, 69, 64, 63, 62, 61, 60, 59, + 58, 57, 56, 55, 54, 53, 52, 51, 50, 45, + 43, 42, 41, 40, 38, 31, 27, 23, 22, 20, + 18, 17, 15, 7, 5, 194, 194, 194, 194, 194, + + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194 } ; 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 #include #include "config_parser.h" extern long __sdp_config_line_num; #define CANNAME 1 -#line 550 "lex.libsdp_yy.c" +#line 581 "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 #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" +#line 738 "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 ) + if ( yy_current_state >= 195 ) 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 ); + while ( yy_base[yy_current_state] != 296 ); 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_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 59 "./config_scanner.l" { + yylval.ival = SUBNET; +#ifdef DEBUG + printf("SUBNET: %s\n", yytext); +#endif + yylval.sval = (char *)malloc(strlen(yytext) + 1); + strcpy(yylval.sval, yytext); + return SUBNET; +} + YY_BREAK +case 3: +YY_RULE_SETUP +#line 69 "./config_scanner.l" +{ yylval.ival = atoi(yytext); #ifdef DEBUG printf("INT:%d\n",yylval.ival); #endif return INT; } YY_BREAK -case 3: +case 4: YY_RULE_SETUP -#line 67 "./config_scanner.l" +#line 77 "./config_scanner.l" { yylval.ival = LOG; #ifdef DEBUG printf("LOG\n"); #endif return LOG; } YY_BREAK -case 4: +case 5: YY_RULE_SETUP -#line 75 "./config_scanner.l" +#line 85 "./config_scanner.l" { yylval.ival = DEST; #ifdef DEBUG printf("DEST\n"); #endif return DEST; } YY_BREAK -case 5: +case 6: YY_RULE_SETUP -#line 83 "./config_scanner.l" +#line 93 "./config_scanner.l" { yylval.ival = LEVEL; #ifdef DEBUG printf("LEVEL\n"); #endif return LEVEL; } YY_BREAK -case 6: +case 7: YY_RULE_SETUP -#line 91 "./config_scanner.l" +#line 101 "./config_scanner.l" { yylval.ival = STDERR; #ifdef DEBUG printf("STDERR\n"); #endif return STDERR; } YY_BREAK -case 7: +case 8: YY_RULE_SETUP -#line 99 "./config_scanner.l" +#line 109 "./config_scanner.l" { yylval.ival = SYSLOG; #ifdef DEBUG printf("SYSLOG\n"); #endif return SYSLOG; } YY_BREAK -case 8: +case 9: YY_RULE_SETUP -#line 107 "./config_scanner.l" +#line 117 "./config_scanner.l" { yylval.ival = FILENAME; #ifdef DEBUG printf("FILENAME\n"); #endif BEGIN(CANNAME); return FILENAME; } YY_BREAK -case 9: +case 10: YY_RULE_SETUP -#line 116 "./config_scanner.l" +#line 126 "./config_scanner.l" { yylval.ival = USE; #ifdef DEBUG printf("USE\n"); #endif return USE; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP -#line 124 "./config_scanner.l" +#line 134 "./config_scanner.l" { yylval.ival = TCP; #ifdef DEBUG printf("TCP\n"); #endif return TCP; } YY_BREAK -case 11: +case 12: YY_RULE_SETUP -#line 132 "./config_scanner.l" +#line 142 "./config_scanner.l" { yylval.ival = SDP; #ifdef DEBUG printf("SDP\n"); #endif return SDP; } YY_BREAK -case 12: +case 13: YY_RULE_SETUP -#line 140 "./config_scanner.l" +#line 150 "./config_scanner.l" { yylval.ival = BOTH; #ifdef DEBUG printf("BOTH\n"); #endif return BOTH; } YY_BREAK -case 13: +case 14: YY_RULE_SETUP -#line 148 "./config_scanner.l" +#line 158 "./config_scanner.l" { yylval.ival = CLIENT; #ifdef DEBUG printf("CLIENT\n"); #endif BEGIN(CANNAME); return CLIENT; } YY_BREAK -case 14: +case 15: YY_RULE_SETUP -#line 157 "./config_scanner.l" +#line 167 "./config_scanner.l" { yylval.ival = SERVER; #ifdef DEBUG printf("SERVER\n"); #endif BEGIN(CANNAME); return SERVER; } YY_BREAK -case 15: +case 16: YY_RULE_SETUP -#line 166 "./config_scanner.l" +#line 176 "./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: +case 17: YY_RULE_SETUP -#line 176 "./config_scanner.l" +#line 186 "./config_scanner.l" { __sdp_config_line_num++; #ifdef DEBUG printf("LINE\n"); #endif yylval.ival = LINE; return(LINE); } YY_BREAK -case 17: +case 18: YY_RULE_SETUP -#line 185 "./config_scanner.l" +#line 195 "./config_scanner.l" { __sdp_config_line_num++; } YY_BREAK -case 18: +case 19: YY_RULE_SETUP -#line 189 "./config_scanner.l" +#line 199 "./config_scanner.l" {} YY_BREAK -case 19: +case 20: YY_RULE_SETUP -#line 191 "./config_scanner.l" +#line 201 "./config_scanner.l" { #ifdef DEBUG printf("CHAR:%c\n",yytext[0]); #endif return(yytext[0]); } YY_BREAK -case 20: +case 21: YY_RULE_SETUP -#line 198 "./config_scanner.l" +#line 208 "./config_scanner.l" ECHO; YY_BREAK -#line 994 "lex.libsdp_yy.c" +#line 1041 "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 ) + if ( yy_current_state >= 195 ) 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 ) + if ( yy_current_state >= 195 ) 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); + yy_is_jam = (yy_current_state == 194); 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" +#line 208 "./config_scanner.l" int yywrap () { return (1); } Index: head/contrib/ofed/libsdp/src/config_scanner.l =================================================================== --- head/contrib/ofed/libsdp/src/config_scanner.l (nonexistent) +++ head/contrib/ofed/libsdp/src/config_scanner.l (revision 296402) @@ -0,0 +1,214 @@ +/* + * 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 $ + */ + +%{ + +/* #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 +#include +#include "config_parser.h" +extern long __sdp_config_line_num; +%} +%s CANNAME +%% + +^[ \t]*#.* {} + +::|[0-9a-f:\.]*[0-9a-f](\/[0-9]+)?/:[0-9*] { + yylval.ival = SUBNET; +#ifdef DEBUG + printf("SUBNET: %s\n", yytext); +#endif + yylval.sval = (char *)malloc(strlen(yytext) + 1); + strcpy(yylval.sval, yytext); + return SUBNET; +} + +([1-9][0-9]*|0) { + yylval.ival = atoi(yytext); +#ifdef DEBUG + printf("INT:%d\n",yylval.ival); +#endif + return INT; +} + +log { + yylval.ival = LOG; +#ifdef DEBUG + printf("LOG\n"); +#endif + return LOG; +} + +destination { + yylval.ival = DEST; +#ifdef DEBUG + printf("DEST\n"); +#endif + return DEST; +} + +min-level { + yylval.ival = LEVEL; +#ifdef DEBUG + printf("LEVEL\n"); +#endif + return LEVEL; +} + +stderr { + yylval.ival = STDERR; +#ifdef DEBUG + printf("STDERR\n"); +#endif + return STDERR; +} + +syslog { + yylval.ival = SYSLOG; +#ifdef DEBUG + printf("SYSLOG\n"); +#endif + return SYSLOG; +} + +file { + yylval.ival = FILENAME; +#ifdef DEBUG + printf("FILENAME\n"); +#endif + BEGIN(CANNAME); + return FILENAME; +} + +use { + yylval.ival = USE; +#ifdef DEBUG + printf("USE\n"); +#endif + return USE; +} + +tcp { + yylval.ival = TCP; +#ifdef DEBUG + printf("TCP\n"); +#endif + return TCP; +} + +sdp { + yylval.ival = SDP; +#ifdef DEBUG + printf("SDP\n"); +#endif + return SDP; +} + +both { + yylval.ival = BOTH; +#ifdef DEBUG + printf("BOTH\n"); +#endif + return BOTH; +} + +client|connect { + yylval.ival = CLIENT; +#ifdef DEBUG + printf("CLIENT\n"); +#endif + BEGIN(CANNAME); + return CLIENT; +} + +server|listen { + yylval.ival = SERVER; +#ifdef DEBUG + printf("SERVER\n"); +#endif + BEGIN(CANNAME); + return SERVER; +} + +[^ \t\n]+ { + yylval.sval = (char *)malloc(strlen(yytext) + 1); + strcpy(yylval.sval, yytext); +#ifdef DEBUG + printf("NAME:%s\n",yylval.sval); +#endif + BEGIN(0); + return (NAME); +} + +\n { + __sdp_config_line_num++; +#ifdef DEBUG + printf("LINE\n"); +#endif + yylval.ival = LINE; + return(LINE); +} + +[#][^\n]* { + __sdp_config_line_num++; +} + +[ \t]+ {} + +. { +#ifdef DEBUG + printf("CHAR:%c\n",yytext[0]); +#endif + return(yytext[0]); +} + +%% + +int yywrap () +{ + return (1); +} + Index: head/contrib/ofed/libsdp/src/libsdp.h =================================================================== --- head/contrib/ofed/libsdp/src/libsdp.h (revision 296401) +++ head/contrib/ofed/libsdp/src/libsdp.h (revision 296402) @@ -1,131 +1,124 @@ /* 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 , or the OpenIB.org BSD license, available in the LICENSE.TXT file accompanying this software. These details are also available at . 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 /* * 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 */ + int match_by_addr; /* if 0 ignore address match */ + struct sockaddr_storage ip; /* IPv4/6 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 ); Index: head/contrib/ofed/libsdp/src/match.c =================================================================== --- head/contrib/ofed/libsdp/src/match.c (revision 296401) +++ head/contrib/ofed/libsdp/src/match.c (revision 296402) @@ -1,296 +1,340 @@ /* 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 , or the OpenIB.org BSD license, available in the LICENSE.TXT file accompanying this software. These details are also available at . 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 #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include +#include +#ifdef __linux__ +#include +#elif defined(__FreeBSD__) +#define s6_addr32 __u6_addr.__u6_addr32 +#define __be32 uint32_t +#endif /* * 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 ) ); + char tmp[INET6_ADDRSTRLEN] = "BAD ADDRESS"; + + if (rule->ip.ss_family == AF_INET) + inet_ntop(AF_INET, &((struct sockaddr_in *)&rule->ip)->sin_addr, tmp, sizeof(tmp)); + else if (rule->ip.ss_family == AF_INET6) + inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&rule->ip)->sin6_addr, tmp, sizeof(tmp)); + + sprintf( addr_buf, "%s/%d", tmp, rule->prefixlen); } 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 ); } +static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, + unsigned int prefixlen) +{ + unsigned pdw, pbi; + + /* check complete u32 in prefix */ + pdw = prefixlen >> 5; + if (pdw && memcmp(a1, a2, pdw << 2)) + return 0; + + /* check incomplete u32 in prefix */ + pbi = prefixlen & 0x1f; + if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi)))) + return 0; + + return 1; +} + +static inline int ipv6_prefix_equal(const struct in6_addr *a1, + const struct in6_addr *a2, + unsigned int prefixlen) +{ + return __ipv6_prefix_equal(a1->s6_addr32, a2->s6_addr32, + prefixlen); +} + /* return 0 if the addresses match */ static inline int -match_ipv4_addr( +match_addr( struct use_family_rule *rule, - const struct sockaddr_in *sin ) + const struct sockaddr *addr_in ) { - return ( rule->ipv4.s_addr != - ( sin->sin_addr. - s_addr & htonl( SDP_NETMASK( rule->prefixlen ) ) ) ); + const struct sockaddr_in *sin = ( const struct sockaddr_in * )addr_in; + const struct sockaddr_in6 *sin6 = ( const struct sockaddr_in6 * )addr_in; + const struct sockaddr_in *rule_sin = ( const struct sockaddr_in * )(&rule->ip); + const struct sockaddr_in6 *rule_sin6 = ( const struct sockaddr_in6 * )(&rule->ip); + + if (rule_sin->sin_family == AF_INET && !rule_sin->sin_addr.s_addr) + return 0; + + if (addr_in->sa_family != rule->ip.ss_family) + return -1; + + if (addr_in->sa_family == AF_INET) { + return ( rule_sin->sin_addr.s_addr != + ( sin->sin_addr.s_addr & + htonl( SDP_NETMASK( rule->prefixlen ) ) ) ); + } + + /* IPv6 */ + return !ipv6_prefix_equal(&sin6->sin6_addr, &rule_sin6->sin6_addr, 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 ); + 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 ); + 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 ); + 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 ) ) { + if ( match_addr( rule, addr_in ) ) { __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 ); } Index: head/contrib/ofed/libsdp/src/port.c =================================================================== --- head/contrib/ofed/libsdp/src/port.c (revision 296401) +++ head/contrib/ofed/libsdp/src/port.c (revision 296402) @@ -1,2636 +1,2643 @@ /* 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 , or the OpenIB.org BSD license, available in the LICENSE.TXT file accompanying this software. These details are also available at . 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 #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 #endif #ifdef __FreeBSD__ #include #endif #include #include #include #include #include #define __USE_GNU #define _GNU_SOURCE /* define RTLD_NEXT */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ #include #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.. */ #if defined(SOLARIS_BUILD) || defined(__FreeBSD__) 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", + __sdp_log(8, "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); + __sdp_log(8, "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); + __sdp_log(8, "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: " + __sdp_log(8, "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:" + __sdp_log(8, "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); + * __sdp_log(8, "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); + if (!(AF_INET == domain || AF_INET6 == domain || + AF_INET_SDP == domain || AF_INET6_SDP == domain)) { + __sdp_log(1, "SOCKET: making other socket\n"); + s = __create_socket_semantic(domain, type, protocol, semantics); + goto done; + } + 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, + __sdp_log(8, "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: " + __sdp_log(8, "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"); + __sdp_log(8, "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", + __sdp_log(8, "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"); + __sdp_log(8, "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"); + __sdp_log(8, "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: " + __sdp_log(8, "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(8, "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", + __sdp_log(8, "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: " + __sdp_log(8, "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: " + __sdp_log(8, "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"); + __sdp_log(8, "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"); + __sdp_log(8, "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"); + __sdp_log(8, "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", + __sdp_log(8, "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: " + __sdp_log(8, "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"); + __sdp_log(8, "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, + __sdp_log(8, "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"); + __sdp_log(8, "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", + __sdp_log(8, "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: " + __sdp_log(7, "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", + __sdp_log(8, "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, + __sdp_log(8, "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", + __sdp_log(8, "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", + __sdp_log(8, "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: " + __sdp_log(8, "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: " + __sdp_log(8, "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", + __sdp_log(8, "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", + __sdp_log(8, "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", + __sdp_log(8, "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", + __sdp_log(8, "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); + __sdp_log(8, "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", + __sdp_log(8, "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, + __sdp_log(8, "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); + __sdp_log(8, "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", + __sdp_log(8, "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"); + __sdp_log(8, "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"); + __sdp_log(8, "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"); + __sdp_log(8, "Error getsockname: illegal address provided\n"); return -1; } if ((namelen != NULL) && is_invalid_addr(namelen)) { errno = EFAULT; - __sdp_log(9, + __sdp_log(8, "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"); + __sdp_log(8, "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"); + __sdp_log(8, "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", + __sdp_log(8, "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, + __sdp_log(8, "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>", + __sdp_log(8, "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 #ifdef __FreeBSD__ program_invocation_short_name = (char *)getprogname(); program_invocation_name = program_invocation_short_name; #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 */ Index: head/contrib/ofed/usr.lib/libsdp/Makefile =================================================================== --- head/contrib/ofed/usr.lib/libsdp/Makefile (revision 296401) +++ head/contrib/ofed/usr.lib/libsdp/Makefile (revision 296402) @@ -1,21 +1,25 @@ # $FreeBSD$ SHLIBDIR?= /usr/lib .include SDPDIR= ${.CURDIR}/../../libsdp/src .PATH: ${SDPDIR} LIB= ibsdp SHLIB_MAJOR= 1 MK_PROFILE= no MAN= SRCS= log.c match.c port.c config_parser.c config_scanner.c CFLAGS+= -DSYSCONFDIR=\"/etc\" CFLAGS+= -I${OFEDSYS}/include .include + +# Remove .[ly] since the checked-in version is preferred. +.SUFFIXES: +.SUFFIXES: .o .po .So .c .ln