libexplain  1.4.D001
libexplain/iocontrol/siocshwtstamp.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2010, 2011, 2013 Peter Miller
00004  * Written by Peter Miller <pmiller@opensource.org.au>
00005  *
00006  * This program is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 3 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful, but WITHOUT
00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include <libexplain/ac/errno.h>
00021 #include <libexplain/ac/linux/net_tstamp.h>
00022 #include <libexplain/ac/linux/sockios.h>
00023 #include <libexplain/ac/net/if.h>
00024 #include <libexplain/ac/sys/ioctl.h>
00025 #include <libexplain/ac/linux/net_tstamp.h>
00026 
00027 #include <libexplain/buffer/dac.h>
00028 #include <libexplain/buffer/einval.h>
00029 #include <libexplain/buffer/eperm.h>
00030 #include <libexplain/buffer/ifreq_data/hwtstamp_config.h>
00031 #include <libexplain/capability.h>
00032 #include <libexplain/iocontrol/generic.h>
00033 #include <libexplain/iocontrol/siocshwtstamp.h>
00034 #include <libexplain/is_efault.h>
00035 
00036 #ifdef SIOCSHWTSTAMP
00037 
00038 
00039 static void
00040 print_data(const explain_iocontrol_t *p, explain_string_buffer_t *sb,
00041     int errnum, int fildes, int request, const void *data)
00042 {
00043     (void)p;
00044     (void)errnum;
00045     (void)fildes;
00046     (void)request;
00047     explain_buffer_ifreq_data_hwtstamp_config(sb, data);
00048 }
00049 
00050 
00051 static void
00052 print_explanation(const explain_iocontrol_t *p, explain_string_buffer_t *sb,
00053     int errnum, int fildes, int request, const void *data)
00054 {
00055     switch (errnum)
00056     {
00057     case EPERM:
00058         if (!explain_capability_net_admin())
00059         {
00060             explain_buffer_eperm_net_admin(sb, "ioctl SIOCSHWTSTAMP");
00061             explain_buffer_dac_net_admin(sb);
00062             break;
00063         }
00064         goto generic;
00065 
00066 #ifdef HAVE_LINUX_NET_TSTAMP_H
00067     case EINVAL:
00068         {
00069             const struct ifreq *rq;
00070 
00071             rq = data;
00072             if (!explain_is_efault_pointer(rq, sizeof(*rq)))
00073             {
00074                 const struct hwtstamp_config *cfg;
00075 
00076                 cfg = (void *)rq->ifr_data;
00077                 if
00078                 (
00079                     !explain_is_efault_pointer(cfg, sizeof(*cfg))
00080                 &&
00081                     cfg->flags != 0
00082                 )
00083                 {
00084                     explain_buffer_einval_vague(sb, "data->ifr_data->flags");
00085                     break;
00086                 }
00087             }
00088          }
00089          goto generic;
00090 
00091     case ERANGE:
00092          {
00093             const struct ifreq *rq;
00094 
00095             rq = data;
00096             if (!explain_is_efault_pointer(rq, sizeof(*rq)))
00097             {
00098                 const struct hwtstamp_config *cfg;
00099 
00100                 cfg = (void *)rq->ifr_data;
00101                 if (!explain_is_efault_pointer(cfg, sizeof(*cfg)))
00102                 {
00103                     int             ok;
00104 
00105                     switch (cfg->tx_type)
00106                     {
00107                     case HWTSTAMP_TX_OFF:
00108                     case HWTSTAMP_TX_ON:
00109                         ok = 1;
00110                         break;
00111 
00112                     default:
00113                         ok = 0;
00114                         break;
00115                     }
00116                     if (!ok)
00117                     {
00118                         explain_buffer_einval_vague
00119                         (
00120                             sb,
00121                             "data->ifr_data->tx_type"
00122                         );
00123                         return;
00124                     }
00125 
00126                     switch (cfg->rx_filter)
00127                     {
00128                     case HWTSTAMP_FILTER_NONE:
00129                     case HWTSTAMP_FILTER_ALL:
00130                     case HWTSTAMP_FILTER_SOME:
00131                     case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
00132                     case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
00133                     case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
00134                     case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
00135                     case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
00136                     case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
00137                     case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
00138                     case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
00139                     case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
00140                     case HWTSTAMP_FILTER_PTP_V2_EVENT:
00141                     case HWTSTAMP_FILTER_PTP_V2_SYNC:
00142                     case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
00143                         ok = 1;
00144                         break;
00145 
00146                     default:
00147                         ok = 0;
00148                     }
00149                     if (!ok)
00150                     {
00151                         explain_buffer_einval_vague
00152                         (
00153                             sb,
00154                             "data->ifr_data->rx_filter"
00155                         );
00156                         return;
00157                     }
00158                 }
00159             }
00160         }
00161         goto generic;
00162 
00163 #endif
00164 
00165     default:
00166         generic:
00167         explain_iocontrol_generic_print_explanation
00168         (
00169             p,
00170             sb,
00171             errnum,
00172             fildes,
00173             request,
00174             data
00175         );
00176         break;
00177     }
00178 }
00179 
00180 
00181 const explain_iocontrol_t explain_iocontrol_siocshwtstamp =
00182 {
00183     "SIOCSHWTSTAMP", /* name */
00184     SIOCSHWTSTAMP, /* value */
00185     0, /* disambiguate */
00186     0, /* print_name */
00187     print_data,
00188     print_explanation,
00189     print_data, /* print_data_returned */
00190     sizeof(struct ifreq), /* data_size */
00191     "struct ifreq *", /* data_type */
00192     IOCONTROL_FLAG_NON_META, /* flags */
00193     __FILE__,
00194     __LINE__,
00195 };
00196 
00197 #else /* ndef SIOCSHWTSTAMP */
00198 
00199 const explain_iocontrol_t explain_iocontrol_siocshwtstamp =
00200 {
00201     0, /* name */
00202     0, /* value */
00203     0, /* disambiguate */
00204     0, /* print_name */
00205     0, /* print_data */
00206     0, /* print_explanation */
00207     0, /* print_data_returned */
00208     0, /* data_size */
00209     0, /* data_type */
00210     0, /* flags */
00211     __FILE__,
00212     __LINE__,
00213 };
00214 
00215 #endif /* SIOCSHWTSTAMP */
00216 
00217 
00218 /* vim: set ts=8 sw=4 et : */