libexplain
1.4.D001
|
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 : */