libexplain  1.4.D001
libexplain/buffer/errno/socket.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2008-2010, 2013 Peter Miller
00004  *
00005  * This program is free software; you can redistribute it and/or modify it
00006  * under the terms of the GNU Lesser General Public License as published by
00007  * the Free Software Foundation; either version 3 of the License, or (at
00008  * 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/errno.h>
00020 #include <libexplain/ac/netdb.h>
00021 
00022 #include <libexplain/buffer/address_family.h>
00023 #include <libexplain/buffer/dac.h>
00024 #include <libexplain/buffer/emfile.h>
00025 #include <libexplain/buffer/enfile.h>
00026 #include <libexplain/buffer/enobufs.h>
00027 #include <libexplain/buffer/enomem.h>
00028 #include <libexplain/buffer/errno/generic.h>
00029 #include <libexplain/buffer/errno/socket.h>
00030 #include <libexplain/buffer/socket_protocol.h>
00031 #include <libexplain/buffer/socket_type.h>
00032 #include <libexplain/explanation.h>
00033 
00034 
00035 static void
00036 explain_buffer_errno_socket_system_call(explain_string_buffer_t *sb,
00037     int errnum, int family, int type, int protocol)
00038 {
00039     (void)errnum;
00040     explain_string_buffer_puts(sb, "socket(family = ");
00041     explain_buffer_address_family(sb, family);
00042     explain_string_buffer_puts(sb, ", type = ");
00043     explain_buffer_socket_type(sb, type);
00044     explain_string_buffer_puts(sb, ", protocol = ");
00045     explain_buffer_socket_protocol(sb, protocol);
00046     explain_string_buffer_putc(sb, ')');
00047 
00048     /*
00049      * Afterwards,
00050      *     getsockname(2);sa.sa_family
00051      *         can be used to retrieve the 'family'
00052      *     getsockopt(fildes, SOL_SOCKET, SO_TYPE, ...)
00053      *         can be used to retrieve the 'type'
00054      *     lsof(1) ... or the techniques it uses, on Linux
00055      *         can be used to retrieve the 'protocol'
00056      */
00057 }
00058 
00059 
00060 void
00061 explain_buffer_errno_socket_explanation(explain_string_buffer_t *sb,
00062     int errnum, const char *syscall_name, int family, int type, int protocol)
00063 {
00064     /*
00065      * http://www.opengroup.org/onlinepubs/009695399/functions/socket.html
00066      *
00067      * Domain     Types...                                  See Also
00068      * AF_UNIX    SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET   unix(7)
00069      * AF_INET                                              ip(7)
00070      * AF_NETLINK                                           netlink(7)
00071      * AF_X25     SOCK_SEQPACKET                            x25(7)
00072      * AF_AX25                                              ax25(4)
00073      * AF_APPLETALK                                         ddp(7), atalk(4)
00074      * AF_PACKET                                            packet(7)
00075      * AF_NETROM                                            netrom(4)
00076      * AF_ROSE                                              rose(4)
00077      * AF_RAW                                               raw(7)
00078      */
00079     (void)family;
00080     (void)type;
00081     (void)protocol;
00082     switch (errnum)
00083     {
00084     case EACCES:
00085     case EPERM:
00086         explain_string_buffer_puts
00087         (
00088             sb,
00089             "the process does not have permission to create a socket of "
00090             "the specified type and/or protocol"
00091         );
00092 #if defined(SOCK_RAW) || defined(SOCK_PACKET)
00093         switch (type)
00094         {
00095 #ifdef SOCK_RAW
00096         case SOCK_RAW:
00097 #endif
00098 #ifdef SOCK_PACKET
00099         case SOCK_PACKET:
00100 #endif
00101             explain_buffer_dac_net_raw(sb);
00102             break;
00103 
00104         default:
00105             break;
00106         }
00107 #endif
00108         break;
00109 
00110     case EAFNOSUPPORT:
00111         explain_string_buffer_puts
00112         (
00113             sb,
00114             "the operating system does not support the specified "
00115             "address family"
00116         );
00117         break;
00118 
00119     case EINVAL:
00120         explain_string_buffer_puts
00121         (
00122             sb,
00123             "unknown protocol, or protocol family not available"
00124         );
00125         break;
00126 
00127     case EMFILE:
00128         explain_buffer_emfile(sb);
00129         break;
00130 
00131     case ENFILE:
00132         explain_buffer_enfile(sb);
00133         break;
00134 
00135     case ENOMEM:
00136         explain_buffer_enomem_kernel(sb);
00137         break;
00138 
00139     case ENOBUFS:
00140         explain_buffer_enobufs(sb);
00141         break;
00142 
00143     case EPROTONOSUPPORT:
00144         explain_string_buffer_puts
00145         (
00146             sb,
00147             "the protocol type or the specified protocol is not "
00148             "supported within this address family"
00149         );
00150         break;
00151 
00152     default:
00153         explain_buffer_errno_generic(sb, errnum, syscall_name);
00154         break;
00155     }
00156 }
00157 
00158 
00159 void
00160 explain_buffer_errno_socket(explain_string_buffer_t *sb, int errnum,
00161     int family, int type, int protocol)
00162 {
00163     explain_explanation_t exp;
00164 
00165     explain_explanation_init(&exp, errnum);
00166     explain_buffer_errno_socket_system_call
00167     (
00168         &exp.system_call_sb,
00169         errnum,
00170         family,
00171         type,
00172         protocol
00173     );
00174     explain_buffer_errno_socket_explanation
00175     (
00176         &exp.explanation_sb,
00177         errnum,
00178         "socket",
00179         family,
00180         type,
00181         protocol
00182     );
00183     explain_explanation_assemble(&exp, sb);
00184 }
00185 
00186 
00187 /* vim: set ts=8 sw=4 et : */