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