libexplain  1.4.D001
libexplain/buffer/route_struct.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2009, 2011, 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/arpa/inet.h>
00020 #include <libexplain/ac/linux/x25.h>
00021 #include <libexplain/ac/net/route.h>
00022 #include <libexplain/ac/netax25/ax25.h>
00023 #include <libexplain/ac/netrom/netrom.h>
00024 #include <libexplain/ac/netrose/rose.h>
00025 
00026 #include <libexplain/buffer/hexdump.h>
00027 #include <libexplain/buffer/int.h>
00028 #include <libexplain/buffer/pathname.h>
00029 #include <libexplain/buffer/pointer.h>
00030 #include <libexplain/buffer/route_struct.h>
00031 #include <libexplain/buffer/rtentry.h>
00032 #include <libexplain/buffer/sockaddr.h>
00033 #include <libexplain/fildes_to_address_family.h>
00034 #include <libexplain/parse_bits.h>
00035 #include <libexplain/is_efault.h>
00036 #include <libexplain/sizeof.h>
00037 
00038 
00039 #ifdef HAVE_NETAX25_AX25_H
00040 
00041 static void
00042 explain_buffer_ax25_address(explain_string_buffer_t *sb,
00043     const ax25_address *data)
00044 {
00045     if (explain_is_efault_pointer(data, sizeof(*data)))
00046     {
00047         explain_buffer_pointer(sb, data);
00048         return;
00049     }
00050 
00051     explain_string_buffer_puts(sb, "{ ax25_call =");
00052     explain_buffer_hexdump(sb, data->ax25_call, sizeof(data->ax25_call));
00053     explain_string_buffer_puts(sb, " }");
00054 
00055 }
00056 
00057 
00058 static void
00059 explain_buffer_ax25_routes_struct(explain_string_buffer_t *sb,
00060     const struct ax25_routes_struct *data)
00061 {
00062     unsigned        j;
00063 
00064     if (explain_is_efault_pointer(data, sizeof(*data)))
00065     {
00066         explain_buffer_pointer(sb, data);
00067         return;
00068     }
00069 
00070     explain_string_buffer_puts(sb, "{ port_addr = ");
00071     explain_buffer_ax25_address(sb, &data->port_addr);
00072     explain_string_buffer_puts(sb, ", dest_addr = ");
00073     explain_buffer_ax25_address(sb, &data->dest_addr);
00074     explain_string_buffer_printf
00075     (
00076         sb,
00077         ", digi_count = %u, digi_addr = {",
00078         data->digi_count
00079     );
00080     for (j = 0; j < data->digi_count && j < AX25_MAX_DIGIS; ++j)
00081     {
00082         explain_string_buffer_puts(sb, ", ");
00083         explain_buffer_ax25_address(sb, &data->digi_addr[j]);
00084     }
00085     explain_string_buffer_puts(sb, " } }");
00086 }
00087 
00088 #endif
00089 
00090 #ifdef HAVE_NETROM_NETROM_H
00091 
00092 static void
00093 explain_buffer_netrom_route_type(explain_string_buffer_t *sb, int data)
00094 {
00095     static const explain_parse_bits_table_t table[] =
00096     {
00097         { "NETROM_NEIGH", NETROM_NEIGH },
00098         { "NETROM_NODE", NETROM_NODE },
00099     };
00100 
00101     explain_parse_bits_print_single(sb, data, table, SIZEOF(table));
00102 }
00103 
00104 static void
00105 explain_buffer_nr_route_struct(explain_string_buffer_t *sb,
00106     const struct nr_route_struct *data)
00107 {
00108     unsigned        j;
00109 
00110     if (explain_is_efault_pointer(data, sizeof(*data)))
00111     {
00112         explain_buffer_pointer(sb, data);
00113         return;
00114     }
00115 
00116     explain_string_buffer_puts(sb, "{ type = ");
00117     explain_buffer_netrom_route_type(sb, data->type);
00118     explain_string_buffer_puts(sb, ", callsign = ");
00119     explain_buffer_ax25_address(sb, &data->callsign);
00120     explain_string_buffer_puts(sb, ", device = ");
00121     explain_string_buffer_puts_quoted(sb, data->device);
00122     explain_string_buffer_printf(sb, ", quality = %u, ", data->quality);
00123     explain_string_buffer_puts(sb, "mnemonic = ");
00124     explain_string_buffer_puts_quoted_n
00125     (
00126         sb,
00127         data->mnemonic,
00128         sizeof(data->mnemonic)
00129     );
00130     explain_string_buffer_puts(sb, ", neighbour = ");
00131     explain_buffer_ax25_address(sb, &data->neighbour);
00132     explain_string_buffer_printf(sb, ", obs_count = %u, ", data->obs_count);
00133     explain_string_buffer_printf(sb, "ndigis = %u, ", data->ndigis);
00134     explain_string_buffer_puts(sb, ", digipeaters = {");
00135     for (j = 0; j < data->ndigis && j < AX25_MAX_DIGIS; ++j)
00136     {
00137         if (j)
00138             explain_string_buffer_putc(sb, ',');
00139         explain_string_buffer_putc(sb, ' ');
00140         explain_buffer_ax25_address(sb, &data->digipeaters[j]);
00141     }
00142     explain_string_buffer_puts(sb, " } }");
00143 }
00144 
00145 #endif
00146 #ifdef __linux__
00147 
00148 static void
00149 explain_buffer_in6_addr(explain_string_buffer_t *sb,
00150     const struct in6_addr *data)
00151 {
00152     char            straddr[200];
00153 
00154     inet_ntop(AF_INET6, data, straddr, sizeof(straddr));
00155     explain_string_buffer_puts(sb, straddr);
00156 }
00157 
00158 
00159 static void
00160 explain_buffer_rtmsg_type(explain_string_buffer_t *sb,
00161     unsigned long data)
00162 {
00163     static const explain_parse_bits_table_t table[] =
00164     {
00165 #if 0
00166         /*
00167          * These are defined, but in terms of symbols that are are NOT
00168          * defined.  Sheesh.
00169          */
00170         { "RTMSG_ACK", RTMSG_ACK },
00171         { "RTMSG_OVERRUN", RTMSG_OVERRUN },
00172 #endif
00173 #ifdef RTMSG_NEWDEVICE
00174         { "RTMSG_NEWDEVICE", RTMSG_NEWDEVICE },
00175 #endif
00176 #ifdef RTMSG_DELDEVICE
00177         { "RTMSG_DELDEVICE", RTMSG_DELDEVICE },
00178 #endif
00179 #ifdef RTMSG_NEWROUTE
00180         { "RTMSG_NEWROUTE", RTMSG_NEWROUTE },
00181 #endif
00182 #ifdef RTMSG_DELROUTE
00183         { "RTMSG_DELROUTE", RTMSG_DELROUTE },
00184 #endif
00185 #ifdef RTMSG_NEWRULE
00186         { "RTMSG_NEWRULE", RTMSG_NEWRULE },
00187 #endif
00188 #ifdef RTMSG_DELRULE
00189         { "RTMSG_DELRULE", RTMSG_DELRULE },
00190 #endif
00191 #ifdef RTMSG_CONTROL
00192         { "RTMSG_CONTROL", RTMSG_CONTROL },
00193 #endif
00194 #ifdef RTMSG_AR_FAILED
00195         { "RTMSG_AR_FAILED", RTMSG_AR_FAILED },
00196 #endif
00197     };
00198 
00199     explain_parse_bits_print(sb, data, table, SIZEOF(table));
00200 }
00201 
00202 
00203 static void
00204 explain_buffer_rtmsg_flags(explain_string_buffer_t *sb,
00205     unsigned long data)
00206 {
00207     static const explain_parse_bits_table_t table[] =
00208     {
00209         { "RTF_DEFAULT", RTF_DEFAULT },
00210         { "RTF_ALLONLINK", RTF_ALLONLINK },
00211         { "RTF_ADDRCONF", RTF_ADDRCONF },
00212         { "RTF_LINKRT", RTF_LINKRT },
00213         { "RTF_NONEXTHOP", RTF_NONEXTHOP },
00214         { "RTF_CACHE", RTF_CACHE },
00215         { "RTF_FLOW", RTF_FLOW },
00216         { "RTF_POLICY", RTF_POLICY },
00217         { "RTCF_VALVE", RTCF_VALVE },
00218         { "RTCF_MASQ", RTCF_MASQ },
00219         { "RTCF_NAT", RTCF_NAT },
00220         { "RTCF_DOREDIRECT", RTCF_DOREDIRECT },
00221         { "RTCF_LOG", RTCF_LOG },
00222         { "RTCF_DIRECTSRC", RTCF_DIRECTSRC },
00223         { "RTF_LOCAL", RTF_LOCAL },
00224         { "RTF_INTERFACE", RTF_INTERFACE },
00225         { "RTF_MULTICAST", RTF_MULTICAST },
00226         { "RTF_BROADCAST", RTF_BROADCAST },
00227         { "RTF_NAT", RTF_NAT },
00228     };
00229 
00230     explain_parse_bits_print(sb, data, table, SIZEOF(table));
00231 }
00232 
00233 
00234 static void
00235 explain_buffer_in6_rtmsg(explain_string_buffer_t *sb,
00236     const struct in6_rtmsg *data)
00237 {
00238     if (explain_is_efault_pointer(data, sizeof(*data)))
00239     {
00240         explain_buffer_pointer(sb, data);
00241         return;
00242     }
00243 
00244     explain_string_buffer_puts(sb, "{ rtmsg_dst = ");
00245     explain_buffer_in6_addr(sb, &data->rtmsg_dst);
00246     explain_string_buffer_puts(sb, ", rtmsg_src = ");
00247     explain_buffer_in6_addr(sb, &data->rtmsg_src);
00248     explain_string_buffer_puts(sb, ", rtmsg_gateway = ");
00249     explain_buffer_in6_addr(sb, &data->rtmsg_gateway);
00250     explain_string_buffer_puts(sb, ", rtmsg_type = ");
00251     explain_buffer_rtmsg_type(sb, data->rtmsg_type);
00252     explain_string_buffer_printf
00253     (
00254         sb,
00255         ", rtmsg_dst_len = %u, ",
00256         data->rtmsg_dst_len
00257     );
00258     explain_string_buffer_printf
00259     (
00260         sb,
00261         "rtmsg_src_len = %u, ",
00262         data->rtmsg_src_len
00263     );
00264     explain_string_buffer_printf
00265     (
00266         sb,
00267         "rtmsg_metric = %lu, ",
00268         (unsigned long)data->rtmsg_metric
00269     );
00270     explain_string_buffer_printf
00271     (
00272         sb,
00273         "rtmsg_info = %lu, ",
00274         data->rtmsg_info
00275     );
00276     explain_string_buffer_puts(sb, "rtmsg_flags = ");
00277     explain_buffer_rtmsg_flags(sb, data->rtmsg_flags);
00278     explain_string_buffer_printf
00279     (
00280         sb,
00281         ", rtmsg_ifindex = %d }",
00282         data->rtmsg_ifindex
00283     );
00284 }
00285 
00286 #endif
00287 #ifdef HAVE_NETROSE_ROSE_H
00288 
00289 static void
00290 explain_buffer_rose_address(explain_string_buffer_t *sb,
00291     const rose_address *data)
00292 {
00293     if (explain_is_efault_pointer(data, sizeof(*data)))
00294     {
00295         explain_buffer_pointer(sb, data);
00296         return;
00297     }
00298 
00299     explain_string_buffer_puts(sb, "{ rose_addr = ");
00300     explain_string_buffer_puts_quoted_n
00301     (
00302         sb,
00303         data->rose_addr,
00304         sizeof(data->rose_addr)
00305     );
00306     explain_string_buffer_puts(sb, " }");
00307 }
00308 
00309 
00310 static void
00311 explain_buffer_rose_route_struct(explain_string_buffer_t *sb,
00312     const struct rose_route_struct *data)
00313 {
00314     unsigned        j;
00315 
00316     if (explain_is_efault_pointer(data, sizeof(*data)))
00317     {
00318         explain_buffer_pointer(sb, data);
00319         return;
00320     }
00321 
00322     explain_string_buffer_puts(sb, "{ address = ");
00323     explain_buffer_rose_address(sb, &data->address);
00324     explain_string_buffer_printf(sb, ", mask = %u, ", data->mask);
00325     explain_string_buffer_puts(sb, "neighbour = ");
00326     explain_buffer_ax25_address(sb, &data->neighbour);
00327     explain_string_buffer_puts(sb, ", device = ");
00328     explain_string_buffer_puts_quoted_n
00329     (
00330         sb,
00331         data->device,
00332         sizeof(data->device)
00333     );
00334     explain_string_buffer_printf(sb, ", ndigis = %u, ", data->ndigis);
00335     explain_string_buffer_puts(sb, "digipeaters = {");
00336     for (j = 0; j < data->ndigis && j < AX25_MAX_DIGIS; ++j)
00337     {
00338         if (j)
00339             explain_string_buffer_putc(sb, ',');
00340         explain_string_buffer_putc(sb, ' ');
00341         explain_buffer_ax25_address(sb, &data->digipeaters[j]);
00342     }
00343     explain_string_buffer_puts(sb, " } }");
00344 }
00345 
00346 #endif
00347 #ifdef HAVE_LINUX_X25_H
00348 
00349 static void
00350 explain_buffer_x25_address(explain_string_buffer_t *sb,
00351     const struct x25_address *data)
00352 {
00353     explain_string_buffer_puts(sb, "{ x25_addr = ");
00354     explain_string_buffer_puts_quoted_n
00355     (
00356         sb,
00357         data->x25_addr,
00358         sizeof(data->x25_addr)
00359     );
00360     explain_string_buffer_puts(sb, " }");
00361 }
00362 
00363 static void
00364 explain_buffer_x25_route_struct(explain_string_buffer_t *sb,
00365     const struct x25_route_struct *data)
00366 {
00367     if (explain_is_efault_pointer(data, sizeof(*data)))
00368     {
00369         explain_buffer_pointer(sb, data);
00370         return;
00371     }
00372 
00373     explain_string_buffer_puts(sb, "{ address = ");
00374     explain_buffer_x25_address(sb, &data->address);
00375     explain_string_buffer_printf(sb, ", sigdigits = %u, ", data->sigdigits);
00376     explain_string_buffer_puts(sb, "device = ");
00377     explain_string_buffer_puts_quoted_n
00378     (
00379         sb,
00380         data->device,
00381         sizeof(data->device)
00382     );
00383     explain_string_buffer_puts(sb, " }");
00384 }
00385 
00386 #endif
00387 
00388 
00389 void
00390 explain_buffer_route_struct(explain_string_buffer_t *sb, int fildes,
00391     const void *data)
00392 {
00393     if (!data)
00394     {
00395         print_pointer:
00396         explain_buffer_pointer(sb, data);
00397         return;
00398     }
00399     switch (explain_fildes_to_address_family(fildes))
00400     {
00401     case -1:
00402         goto print_pointer;
00403 
00404     default:
00405         explain_buffer_rtentry(sb, data);
00406         break;
00407 
00408 #ifdef HAVE_NETAX25_AX25_H
00409     case AF_AX25:
00410         explain_buffer_ax25_routes_struct(sb, data);
00411         break;
00412 #endif
00413 
00414 #ifdef __linux__
00415     case AF_INET6:
00416         explain_buffer_in6_rtmsg(sb, data);
00417         break;
00418 #endif
00419 
00420 #ifdef HAVE_NETROM_NETROM_H
00421     case AF_NETROM:
00422         explain_buffer_nr_route_struct(sb, data);
00423         break;
00424 #endif
00425 
00426 #ifdef HAVE_NETROSE_ROSE_H
00427     case AF_ROSE:
00428         explain_buffer_rose_route_struct(sb, data);
00429         break;
00430 #endif
00431 
00432 #ifdef HAVE_LINUX_X25_H
00433     case AF_X25:
00434         explain_buffer_x25_route_struct(sb, data);
00435         break;
00436 #endif
00437     }
00438 }
00439 
00440 
00441 /* vim: set ts=8 sw=4 et : */