libexplain  1.4.D001
libexplain/buffer/sockopt_name.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2009, 2013 Peter Miller
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU Lesser General Public License as
00007  * published by the Free Software Foundation; either version 3 of the
00008  * License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public License
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #include <libexplain/ac/bluetooth/bluetooth.h>
00020 #include <libexplain/ac/netinet/in.h>
00021 #include <libexplain/ac/stdlib.h>
00022 #include <libexplain/ac/string.h>
00023 #include <libexplain/ac/sys/socket.h>
00024 
00025 #include <libexplain/buffer/sockopt_name.h>
00026 #include <libexplain/parse_bits.h>
00027 #include <libexplain/sizeof.h>
00028 
00029 
00030 static const explain_parse_bits_table_t sol_socket_table[] =
00031 {
00032     { "SO_DEBUG", SO_DEBUG },
00033 #ifdef SO_REUSEADDR
00034     { "SO_REUSEADDR", SO_REUSEADDR },
00035 #endif
00036 #ifdef SO_TYPE
00037     { "SO_TYPE", SO_TYPE },
00038 #endif
00039 #ifdef SO_ERROR
00040     { "SO_ERROR", SO_ERROR },
00041 #endif
00042 #ifdef SO_DONTROUTE
00043     { "SO_DONTROUTE", SO_DONTROUTE },
00044 #endif
00045 #ifdef SO_BROADCAST
00046     { "SO_BROADCAST", SO_BROADCAST },
00047 #endif
00048 #ifdef SO_SNDBUF
00049     { "SO_SNDBUF", SO_SNDBUF },
00050 #endif
00051 #ifdef SO_RCVBUF
00052     { "SO_RCVBUF", SO_RCVBUF },
00053 #endif
00054 #ifdef SO_SNDBUFFORCE
00055     { "SO_SNDBUFFORCE", SO_SNDBUFFORCE },
00056 #endif
00057 #ifdef SO_RCVBUFFORCE
00058     { "SO_RCVBUFFORCE", SO_RCVBUFFORCE },
00059 #endif
00060 #ifdef SO_KEEPALIVE
00061     { "SO_KEEPALIVE", SO_KEEPALIVE },
00062 #endif
00063 #ifdef SO_OOBINLINE
00064     { "SO_OOBINLINE", SO_OOBINLINE },
00065 #endif
00066 #ifdef SO_NO_CHECK
00067     { "SO_NO_CHECK", SO_NO_CHECK },
00068 #endif
00069 #ifdef SO_PRIORITY
00070     { "SO_PRIORITY", SO_PRIORITY },
00071 #endif
00072 #ifdef SO_LINGER
00073     { "SO_LINGER", SO_LINGER },
00074 #endif
00075 #ifdef SO_BSDCOMPAT
00076     { "SO_BSDCOMPAT", SO_BSDCOMPAT },
00077 #endif
00078 #ifdef SO_PASSCRED
00079     { "SO_PASSCRED", SO_PASSCRED },
00080 #endif
00081 #ifdef SO_PEERCRED
00082     { "SO_PEERCRED", SO_PEERCRED },
00083 #endif
00084 #ifdef SO_RCVLOWAT
00085     { "SO_RCVLOWAT", SO_RCVLOWAT },
00086 #endif
00087 #ifdef SO_SNDLOWAT
00088     { "SO_SNDLOWAT", SO_SNDLOWAT },
00089 #endif
00090 #ifdef SO_RCVTIMEO
00091     { "SO_RCVTIMEO", SO_RCVTIMEO },
00092 #endif
00093 #ifdef SO_SNDTIMEO
00094     { "SO_SNDTIMEO", SO_SNDTIMEO },
00095 #endif
00096 #ifdef SO_SECURITY_AUTHENTICATION
00097     { "SO_SECURITY_AUTHENTICATION", SO_SECURITY_AUTHENTICATION },
00098 #endif
00099 #ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
00100     { "SO_SECURITY_ENCRYPTION_TRANSPORT", SO_SECURITY_ENCRYPTION_TRANSPORT },
00101 #endif
00102 #ifdef SO_SECURITY_ENCRYPTION_NETWORK
00103     { "SO_SECURITY_ENCRYPTION_NETWORK", SO_SECURITY_ENCRYPTION_NETWORK },
00104 #endif
00105 #ifdef SO_BINDTODEVICE
00106     { "SO_BINDTODEVICE", SO_BINDTODEVICE },
00107 #endif
00108 #ifdef SO_ATTACH_FILTER
00109     { "SO_ATTACH_FILTER", SO_ATTACH_FILTER },
00110 #endif
00111 #ifdef SO_DETACH_FILTER
00112     { "SO_DETACH_FILTER", SO_DETACH_FILTER },
00113 #endif
00114 #ifdef SO_PEERNAME
00115     { "SO_PEERNAME", SO_PEERNAME },
00116 #endif
00117 #ifdef SO_TIMESTAMP
00118     { "SO_TIMESTAMP", SO_TIMESTAMP },
00119 #endif
00120 #ifdef SO_ACCEPTCONN
00121     { "SO_ACCEPTCONN", SO_ACCEPTCONN },
00122 #endif
00123 #ifdef SO_PEERSEC
00124     { "SO_PEERSEC", SO_PEERSEC },
00125 #endif
00126 #ifdef SO_PASSSEC
00127     { "SO_PASSSEC", SO_PASSSEC },
00128 #endif
00129 #ifdef SO_TIMESTAMPNS
00130     { "SO_TIMESTAMPNS", SO_TIMESTAMPNS },
00131 #endif
00132 #ifdef SCM_TIMESTAMPNS
00133     { "SCM_TIMESTAMPNS", SCM_TIMESTAMPNS },
00134 #endif
00135 #ifdef SO_MARK
00136     { "SO_MARK", SO_MARK },
00137 #endif
00138 
00139     /* <linux/atm.h> */
00140 #ifdef SO_SETCLP
00141     { "SO_SETCLP", SO_SETCLP },
00142 #endif
00143 #ifdef SO_CIRANGE
00144     { "SO_CIRANGE", SO_CIRANGE },
00145 #endif
00146 #ifdef SO_ATMQOS
00147     { "SO_ATMQOS", SO_ATMQOS },
00148 #endif
00149 #ifdef SO_ATMSAP
00150     { "SO_ATMSAP", SO_ATMSAP },
00151 #endif
00152 #ifdef SO_ATMPVC
00153     { "SO_ATMPVC", SO_ATMPVC },
00154 #endif
00155 #ifdef SO_MULTIPOINT
00156     { "SO_MULTIPOINT", SO_MULTIPOINT },
00157 #endif
00158 };
00159 
00160 static const explain_parse_bits_table_t sol_ip_table[] =
00161 {
00162     { "IP_TOS", IP_TOS },
00163 #ifdef IP_TTL
00164     { "IP_TTL", IP_TTL },
00165 #endif
00166 #ifdef IP_HDRINCL
00167     { "IP_HDRINCL", IP_HDRINCL },
00168 #endif
00169 #ifdef IP_OPTIONS
00170     { "IP_OPTIONS", IP_OPTIONS },
00171 #endif
00172 #ifdef IP_ROUTER_ALERT
00173     { "IP_ROUTER_ALERT", IP_ROUTER_ALERT },
00174 #endif
00175 #ifdef IP_RECVOPTS
00176     { "IP_RECVOPTS", IP_RECVOPTS },
00177 #endif
00178 #ifdef IP_RETOPTS
00179     { "IP_RETOPTS", IP_RETOPTS },
00180 #endif
00181 #ifdef IP_PKTINFO
00182     { "IP_PKTINFO", IP_PKTINFO },
00183 #endif
00184 #ifdef IP_PKTOPTIONS
00185     { "IP_PKTOPTIONS", IP_PKTOPTIONS },
00186 #endif
00187 #ifdef IP_PMTUDISC
00188     { "IP_PMTUDISC", IP_PMTUDISC },
00189 #endif
00190 #ifdef IP_MTU_DISCOVER
00191     { "IP_MTU_DISCOVER", IP_MTU_DISCOVER },
00192 #endif
00193 #ifdef IP_RECVERR
00194     { "IP_RECVERR", IP_RECVERR },
00195 #endif
00196 #ifdef IP_RECVTTL
00197     { "IP_RECVTTL", IP_RECVTTL },
00198 #endif
00199 #ifdef IP_RECVTOS
00200     { "IP_RECVTOS", IP_RECVTOS },
00201 #endif
00202 #ifdef IP_MULTICAST_IF
00203     { "IP_MULTICAST_IF", IP_MULTICAST_IF },
00204 #endif
00205 #ifdef IP_MULTICAST_TTL
00206     { "IP_MULTICAST_TTL", IP_MULTICAST_TTL },
00207 #endif
00208 #ifdef IP_MULTICAST_LOOP
00209     { "IP_MULTICAST_LOOP", IP_MULTICAST_LOOP },
00210 #endif
00211 #ifdef IP_ADD_MEMBERSHIP
00212     { "IP_ADD_MEMBERSHIP", IP_ADD_MEMBERSHIP },
00213 #endif
00214 #ifdef IP_DROP_MEMBERSHIP
00215     { "IP_DROP_MEMBERSHIP", IP_DROP_MEMBERSHIP },
00216 #endif
00217 #ifdef IP_UNBLOCK_SOURCE
00218     { "IP_UNBLOCK_SOURCE", IP_UNBLOCK_SOURCE },
00219 #endif
00220 #ifdef IP_BLOCK_SOURCE
00221     { "IP_BLOCK_SOURCE", IP_BLOCK_SOURCE },
00222 #endif
00223 #ifdef IP_ADD_SOURCE_MEMBERSHIP
00224     { "IP_ADD_SOURCE_MEMBERSHIP", IP_ADD_SOURCE_MEMBERSHIP },
00225 #endif
00226 #ifdef IP_DROP_SOURCE_MEMBERSHIP
00227     { "IP_DROP_SOURCE_MEMBERSHIP", IP_DROP_SOURCE_MEMBERSHIP },
00228 #endif
00229 #ifdef IP_MSFILTER
00230     { "IP_MSFILTER", IP_MSFILTER },
00231 #endif
00232 #ifdef MCAST_JOIN_GROUP
00233     { "MCAST_JOIN_GROUP", MCAST_JOIN_GROUP },
00234 #endif
00235 #ifdef MCAST_BLOCK_SOURCE
00236     { "MCAST_BLOCK_SOURCE", MCAST_BLOCK_SOURCE },
00237 #endif
00238 #ifdef MCAST_UNBLOCK_SOURCE
00239     { "MCAST_UNBLOCK_SOURCE", MCAST_UNBLOCK_SOURCE },
00240 #endif
00241 #ifdef MCAST_LEAVE_GROUP
00242     { "MCAST_LEAVE_GROUP", MCAST_LEAVE_GROUP },
00243 #endif
00244 #ifdef MCAST_JOIN_SOURCE_GROUP
00245     { "MCAST_JOIN_SOURCE_GROUP", MCAST_JOIN_SOURCE_GROUP },
00246 #endif
00247 #ifdef MCAST_LEAVE_SOURCE_GROUP
00248     { "MCAST_LEAVE_SOURCE_GROUP", MCAST_LEAVE_SOURCE_GROUP },
00249 #endif
00250 #ifdef MCAST_MSFILTER
00251     { "MCAST_MSFILTER", MCAST_MSFILTER },
00252 #endif
00253 };
00254 
00255 
00256 void
00257 explain_buffer_sockopt_name(explain_string_buffer_t *sb, int level,
00258     int name)
00259 {
00260     switch (level)
00261     {
00262     /* FIXME: add support for SOL_AAL */
00263     /* FIXME: add support for SOL_ATALK */
00264     /* FIXME: add support for SOL_ATM */
00265     /* FIXME: add support for SOL_AX25 */
00266     /* FIXME: add support for SOL_BLUETOOTH */
00267     /* FIXME: add support for SOL_DCCP */
00268     /* FIXME: add support for SOL_DECNET */
00269     /* FIXME: add support for SOL_ICMP */
00270     /* FIXME: add support for SOL_ICMPV6 */
00271 
00272 #ifdef SOL_IP
00273     case SOL_IP:
00274         explain_parse_bits_print_single
00275         (
00276             sb,
00277             name,
00278             sol_ip_table,
00279             SIZEOF(sol_ip_table)
00280         );
00281         break;
00282 #endif
00283 
00284     /* FIXME: add support for SOL_IPV6 */
00285     /* FIXME: add support for SOL_IPX */
00286     /* FIXME: add support for SOL_IRDA */
00287     /* FIXME: add support for SOL_LLC */
00288     /* FIXME: add support for SOL_NETBUEI */
00289     /* FIXME: add support for SOL_NETLINK */
00290     /* FIXME: add support for SOL_NETROM */
00291     /* FIXME: add support for SOL_PACKET */
00292     /* FIXME: add support for SOL_PPPOL2TP */
00293     /* FIXME: add support for SOL_RAW */
00294     /* FIXME: add support for SOL_ROSE */
00295     /* FIXME: add support for SOL_RXRPC */
00296     /* FIXME: add support for SOL_SCTP */
00297 
00298     case SOL_SOCKET:
00299         explain_parse_bits_print_single
00300         (
00301             sb,
00302             name,
00303             sol_socket_table,
00304             SIZEOF(sol_socket_table)
00305         );
00306         break;
00307 
00308     /* FIXME: add support for SOL_TCP */
00309     /* FIXME: add support for SOL_TIPC */
00310     /* FIXME: add support for SOL_UDP */
00311     /* FIXME: add support for SOL_UDPLITE */
00312     /* FIXME: add support for SOL_X25 */
00313 
00314     default:
00315         explain_string_buffer_printf(sb, "%d", name);
00316         break;
00317     }
00318 }
00319 
00320 
00321 typedef struct list_t list_t;
00322 struct list_t
00323 {
00324     explain_parse_bits_table_t *item;
00325     size_t          size;
00326     size_t          max;
00327 };
00328 
00329 
00330 static void
00331 list_constructor(list_t *lp)
00332 {
00333     lp->item = 0;
00334     lp->size = 0;
00335     lp->max = 0;
00336 }
00337 
00338 
00339 static void
00340 list_append(list_t *lp, const explain_parse_bits_table_t *table, size_t size)
00341 {
00342     if (lp->size + size > lp->max)
00343     {
00344         size_t          new_max;
00345         explain_parse_bits_table_t *new_item;
00346 
00347         new_max = lp->max * 2 + 4;
00348         while (lp->size + size > new_max)
00349             new_max = new_max * 2 + 4;
00350         new_item = malloc(sizeof(*new_item) * new_max);
00351         if (!new_item)
00352             return;
00353         memcpy(new_item, lp->item, lp->size * sizeof(*new_item));
00354         if (lp->item)
00355             free(lp->item);
00356         lp->item = new_item;
00357         lp->max = new_max;
00358     }
00359     memcpy(lp->item + lp->size, table, size * sizeof(*table));
00360     lp->size += size;
00361 }
00362 
00363 
00364 static void
00365 list_destructor(list_t *lp)
00366 {
00367     if (lp->item)
00368         free(lp->item);
00369     lp->item = 0;
00370     lp->size = 0;
00371     lp->max = 0;
00372 }
00373 
00374 
00375 int
00376 explain_parse_sockopt_name_or_die(const char *text, const char *caption)
00377 {
00378     list_t          list;
00379     int             result;
00380 
00381     list_constructor(&list);
00382     list_append(&list, sol_ip_table, SIZEOF(sol_ip_table));
00383     list_append(&list, sol_socket_table, SIZEOF(sol_socket_table));
00384     if (!list.item)
00385     {
00386         return
00387             explain_parse_bits_or_die
00388             (
00389                 text,
00390                 sol_socket_table,
00391                 SIZEOF(sol_socket_table),
00392                 caption
00393             );
00394     }
00395     result = explain_parse_bits_or_die(text, list.item, list.size, caption);
00396     list_destructor(&list);
00397     return result;
00398 }
00399 
00400 
00401 /* vim: set ts=8 sw=4 et : */