Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/networking/interface.c
- Timestamp:
- Nov 4, 2007, 3:16:40 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.5/mindi-busybox/networking/interface.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * stolen from net-tools-1.59 and stripped down for busybox by … … 15 16 * one or more of the system's networking interfaces. 16 17 * 17 * Version: $Id: interface.c,v 1.25 2004/08/26 21:45:21 andersen Exp $18 18 * 19 19 * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> … … 32 32 */ 33 33 34 #include "inet_common.h"35 #include <stdio.h>36 #include <errno.h>37 #include <stdlib.h>38 #include <string.h>39 #include <unistd.h>40 #include <fcntl.h>41 #include <ctype.h>42 #include <sys/ioctl.h>43 #include <sys/types.h>44 34 #include <net/if.h> 45 35 #include <net/if_arp.h> 46 #include "busybox.h" 47 48 #ifdef CONFIG_FEATURE_IPV6 36 #include "inet_common.h" 37 #include "libbb.h" 38 39 #if ENABLE_FEATURE_IPV6 49 40 # define HAVE_AFINET6 1 50 41 #else … … 55 46 #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6" 56 47 57 #if HAVE_AFINET648 #ifdef HAVE_AFINET6 58 49 59 50 #ifndef _LINUX_IN6_H … … 70 61 #endif 71 62 72 #endif 63 #endif /* HAVE_AFINET6 */ 73 64 74 65 /* Defines for glibc2.0 users. */ … … 91 82 #endif 92 83 93 /* This structure defines protocol families and their handlers. */94 struct aftype {95 const char *name;96 const char *title;97 int af;98 int alen;99 char *(*print) (unsigned char *);100 char *(*sprint) (struct sockaddr *, int numeric);101 int (*input) (int type, char *bufp, struct sockaddr *);102 void (*herror) (char *text);103 int (*rprint) (int options);104 int (*rinput) (int typ, int ext, char **argv);105 106 /* may modify src */107 int (*getmask) (char *src, struct sockaddr * mask, char *name);108 109 int fd;110 char *flag_file;111 };112 113 84 /* Display an Internet socket address. */ 114 static char *INET_sprint(struct sockaddr *sap, int numeric) 115 { 116 static char buff[128]; 117 85 static const char *INET_sprint(struct sockaddr *sap, int numeric) 86 { 87 static char *buff; 88 89 free(buff); 118 90 if (sap->sa_family == 0xFFFF || sap->sa_family == 0) 119 return safe_strncpy(buff, "[NONE SET]", sizeof(buff)); 120 121 if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap, 122 numeric, 0xffffff00) != 0) 123 return (NULL); 124 125 return (buff); 126 } 127 128 static struct aftype inet_aftype = { 91 return "[NONE SET]"; 92 buff = INET_rresolve((struct sockaddr_in *) sap, numeric, 0xffffff00); 93 return buff; 94 } 95 96 #ifdef UNUSED_AND_BUGGY 97 static int INET_getsock(char *bufp, struct sockaddr *sap) 98 { 99 char *sp = bufp, *bp; 100 unsigned int i; 101 unsigned val; 102 struct sockaddr_in *sock_in; 103 104 sock_in = (struct sockaddr_in *) sap; 105 sock_in->sin_family = AF_INET; 106 sock_in->sin_port = 0; 107 108 val = 0; 109 bp = (char *) &val; 110 for (i = 0; i < sizeof(sock_in->sin_addr.s_addr); i++) { 111 *sp = toupper(*sp); 112 113 if ((unsigned)(*sp - 'A') <= 5) 114 bp[i] |= (int) (*sp - ('A' - 10)); 115 else if (isdigit(*sp)) 116 bp[i] |= (int) (*sp - '0'); 117 else 118 return -1; 119 120 bp[i] <<= 4; 121 sp++; 122 *sp = toupper(*sp); 123 124 if ((unsigned)(*sp - 'A') <= 5) 125 bp[i] |= (int) (*sp - ('A' - 10)); 126 else if (isdigit(*sp)) 127 bp[i] |= (int) (*sp - '0'); 128 else 129 return -1; 130 131 sp++; 132 } 133 sock_in->sin_addr.s_addr = htonl(val); 134 135 return (sp - bufp); 136 } 137 #endif 138 139 static int INET_input(/*int type,*/ const char *bufp, struct sockaddr *sap) 140 { 141 return INET_resolve(bufp, (struct sockaddr_in *) sap, 0); 142 /* 143 switch (type) { 144 case 1: 145 return (INET_getsock(bufp, sap)); 146 case 256: 147 return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1)); 148 default: 149 return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0)); 150 } 151 */ 152 } 153 154 static const struct aftype inet_aftype = { 129 155 .name = "inet", 130 156 .title = "DARPA Internet", … … 132 158 .alen = 4, 133 159 .sprint = INET_sprint, 134 . fd = -1135 }; 136 137 #if HAVE_AFINET6160 .input = INET_input, 161 }; 162 163 #ifdef HAVE_AFINET6 138 164 139 165 /* Display an Internet socket address. */ 140 166 /* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */ 141 static char *INET6_sprint(struct sockaddr *sap, int numeric) 142 { 143 static char buff[128]; 144 167 static const char *INET6_sprint(struct sockaddr *sap, int numeric) 168 { 169 static char *buff; 170 171 free(buff); 145 172 if (sap->sa_family == 0xFFFF || sap->sa_family == 0) 146 return safe_strncpy(buff, "[NONE SET]", sizeof(buff)); 147 if (INET6_rresolve 148 (buff, sizeof(buff), (struct sockaddr_in6 *) sap, numeric) != 0) 149 return safe_strncpy(buff, "[UNKNOWN]", sizeof(buff)); 150 return (buff); 151 } 152 153 static struct aftype inet6_aftype = { 173 return "[NONE SET]"; 174 buff = INET6_rresolve((struct sockaddr_in6 *) sap, numeric); 175 return buff; 176 } 177 178 #ifdef UNUSED 179 static int INET6_getsock(char *bufp, struct sockaddr *sap) 180 { 181 struct sockaddr_in6 *sin6; 182 183 sin6 = (struct sockaddr_in6 *) sap; 184 sin6->sin6_family = AF_INET6; 185 sin6->sin6_port = 0; 186 187 if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0) 188 return -1; 189 190 return 16; /* ?;) */ 191 } 192 #endif 193 194 static int INET6_input(/*int type,*/ const char *bufp, struct sockaddr *sap) 195 { 196 return INET6_resolve(bufp, (struct sockaddr_in6 *) sap); 197 /* 198 switch (type) { 199 case 1: 200 return (INET6_getsock(bufp, sap)); 201 default: 202 return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap)); 203 } 204 */ 205 } 206 207 static const struct aftype inet6_aftype = { 154 208 .name = "inet6", 155 209 .title = "IPv6", … … 157 211 .alen = sizeof(struct in6_addr), 158 212 .sprint = INET6_sprint, 159 . fd = -1160 }; 161 162 #endif 213 .input = INET6_input, 214 }; 215 216 #endif /* HAVE_AFINET6 */ 163 217 164 218 /* Display an UNSPEC address. */ 165 219 static char *UNSPEC_print(unsigned char *ptr) 166 220 { 167 static char buff[sizeof(struct sockaddr) * 3 + 1]; 221 static char *buff; 222 168 223 char *pos; 169 224 unsigned int i; 170 225 226 if (!buff); 227 buff = xmalloc(sizeof(struct sockaddr) * 3 + 1); 171 228 pos = buff; 172 229 for (i = 0; i < sizeof(struct sockaddr); i++) { … … 177 234 /* Erase trailing "-". Works as long as sizeof(struct sockaddr) != 0 */ 178 235 *--pos = '\0'; 179 return (buff);236 return buff; 180 237 } 181 238 182 239 /* Display an UNSPEC socket address. */ 183 static char *UNSPEC_sprint(struct sockaddr *sap, int numeric) 184 { 185 static char buf[64]; 186 240 static const char *UNSPEC_sprint(struct sockaddr *sap, int numeric) 241 { 187 242 if (sap->sa_family == 0xFFFF || sap->sa_family == 0) 188 return safe_strncpy(buf, "[NONE SET]", sizeof(buf)); 189 return (UNSPEC_print((unsigned char *)sap->sa_data)); 190 } 191 192 static struct aftype unspec_aftype = { 193 "unspec", "UNSPEC", AF_UNSPEC, 0, 194 UNSPEC_print, UNSPEC_sprint, NULL, NULL, 195 NULL, 196 }; 197 198 static struct aftype * const aftypes[] = { 243 return "[NONE SET]"; 244 return UNSPEC_print((unsigned char *)sap->sa_data); 245 } 246 247 static const struct aftype unspec_aftype = { 248 .name = "unspec", 249 .title = "UNSPEC", 250 .af = AF_UNSPEC, 251 .alen = 0, 252 .print = UNSPEC_print, 253 .sprint = UNSPEC_sprint, 254 }; 255 256 static const struct aftype *const aftypes[] = { 199 257 &inet_aftype, 200 #if HAVE_AFINET6258 #ifdef HAVE_AFINET6 201 259 &inet6_aftype, 202 260 #endif … … 206 264 207 265 /* Check our protocol family table for this family. */ 208 static struct aftype *get_afntype(int af) 209 { 210 struct aftype * const *afp; 266 const struct aftype *get_aftype(const char *name) 267 { 268 const struct aftype *const *afp; 269 270 afp = aftypes; 271 while (*afp != NULL) { 272 if (!strcmp((*afp)->name, name)) 273 return (*afp); 274 afp++; 275 } 276 return NULL; 277 } 278 279 /* Check our protocol family table for this family. */ 280 static const struct aftype *get_afntype(int af) 281 { 282 const struct aftype *const *afp; 211 283 212 284 afp = aftypes; 213 285 while (*afp != NULL) { 214 286 if ((*afp)->af == af) 215 return (*afp);287 return *afp; 216 288 afp++; 217 289 } 218 return (NULL); 219 } 220 221 /* Check our protocol family table for this family and return its socket */ 222 static int get_socket_for_af(int af) 223 { 224 struct aftype * const *afp; 225 226 afp = aftypes; 227 while (*afp != NULL) { 228 if ((*afp)->af == af) 229 return (*afp)->fd; 230 afp++; 231 } 232 return -1; 290 return NULL; 233 291 } 234 292 … … 284 342 285 343 286 int interface_opt_a = 0; /* show all interfaces*/344 smallint interface_opt_a; /* show all interfaces */ 287 345 288 346 static struct interface *int_list, *int_last; 289 static int skfd = -1; /* generic raw socket desc. */ 290 291 292 static int sockets_open(int family) 293 { 294 struct aftype * const *aft; 295 int sfd = -1; 296 static int force = -1; 297 298 if (force < 0) { 299 force = 0; 300 if (get_linux_version_code() < KERNEL_VERSION(2,1,0)) 301 force = 1; 302 if (access("/proc/net", R_OK)) 303 force = 1; 304 } 305 for (aft = aftypes; *aft; aft++) { 306 struct aftype *af = *aft; 307 int type = SOCK_DGRAM; 308 309 if (af->af == AF_UNSPEC) 310 continue; 311 if (family && family != af->af) 312 continue; 313 if (af->fd != -1) { 314 sfd = af->fd; 315 continue; 316 } 317 /* Check some /proc file first to not stress kmod */ 318 if (!family && !force && af->flag_file) { 319 if (access(af->flag_file, R_OK)) 320 continue; 321 } 322 af->fd = socket(af->af, type, 0); 323 if (af->fd >= 0) 324 sfd = af->fd; 325 } 326 if (sfd < 0) { 327 bb_error_msg("No usable address families found."); 328 } 329 return sfd; 330 } 331 332 #ifdef CONFIG_FEATURE_CLEAN_UP 333 static void sockets_close(void) 334 { 335 struct aftype * const *aft; 336 for (aft = aftypes; *aft != NULL; aft++) { 337 struct aftype *af = *aft; 338 if( af->fd != -1 ) { 339 close(af->fd); 340 af->fd = -1; 341 } 342 } 343 } 344 #endif 345 347 348 349 #if 0 346 350 /* like strcmp(), but knows about numbers */ 351 except that the freshly added calls to xatoul() brf on ethernet aliases with 352 uClibc with e.g.: ife->name='lo' name='eth0:1' 347 353 static int nstrcmp(const char *a, const char *b) 348 354 { … … 363 369 364 370 if (isdigit(*a) && isdigit(*b)) { 365 return atoi(a_ptr) > atoi(b_ptr) ? 1 : -1;371 return xatoul(a_ptr) > xatoul(b_ptr) ? 1 : -1; 366 372 } 367 373 return *a - *b; 368 374 } 375 #endif 369 376 370 377 static struct interface *add_interface(char *name) … … 373 380 374 381 for (ife = int_last; ife; ife = ife->prev) { 375 int n = nstrcmp(ife->name, name);382 int n = /*n*/strcmp(ife->name, name); 376 383 377 384 if (n == 0) … … 392 399 *nextp = new; 393 400 return new; 394 }395 396 397 static int if_readconf(void)398 {399 int numreqs = 30;400 struct ifconf ifc;401 struct ifreq *ifr;402 int n, err = -1;403 int skfd2;404 405 /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets406 (as of 2.1.128) */407 skfd2 = get_socket_for_af(AF_INET);408 if (skfd2 < 0) {409 bb_perror_msg(("warning: no inet socket available"));410 /* Try to soldier on with whatever socket we can get hold of. */411 skfd2 = sockets_open(0);412 if (skfd2 < 0)413 return -1;414 }415 416 ifc.ifc_buf = NULL;417 for (;;) {418 ifc.ifc_len = sizeof(struct ifreq) * numreqs;419 ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len);420 421 if (ioctl(skfd2, SIOCGIFCONF, &ifc) < 0) {422 perror("SIOCGIFCONF");423 goto out;424 }425 if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) {426 /* assume it overflowed and try again */427 numreqs += 10;428 continue;429 }430 break;431 }432 433 ifr = ifc.ifc_req;434 for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {435 add_interface(ifr->ifr_name);436 ifr++;437 }438 err = 0;439 440 out:441 free(ifc.ifc_buf);442 return err;443 401 } 444 402 … … 477 435 * args. */ 478 436 479 /* static const char * 437 /* static const char *const ss_fmt[] = { */ 480 438 /* "%lln%llu%lu%lu%lu%lu%ln%ln%lln%llu%lu%lu%lu%lu%lu", */ 481 439 /* "%llu%llu%lu%lu%lu%lu%ln%ln%llu%llu%lu%lu%lu%lu%lu", */ … … 485 443 /* Lie about the size of the int pointed to for %n. */ 486 444 #if INT_MAX == LONG_MAX 487 static const char * 445 static const char *const ss_fmt[] = { 488 446 "%n%llu%u%u%u%u%n%n%n%llu%u%u%u%u%u", 489 447 "%llu%llu%u%u%u%u%n%n%llu%llu%u%u%u%u%u", … … 491 449 }; 492 450 #else 493 static const char * 451 static const char *const ss_fmt[] = { 494 452 "%n%llu%lu%lu%lu%lu%n%n%n%llu%lu%lu%lu%lu%lu", 495 453 "%llu%llu%lu%lu%lu%lu%n%n%llu%llu%lu%lu%lu%lu%lu", … … 542 500 } 543 501 502 static int if_readconf(void) 503 { 504 int numreqs = 30; 505 struct ifconf ifc; 506 struct ifreq *ifr; 507 int n, err = -1; 508 int skfd; 509 510 ifc.ifc_buf = NULL; 511 512 /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets 513 (as of 2.1.128) */ 514 skfd = socket(AF_INET, SOCK_DGRAM, 0); 515 if (skfd < 0) { 516 bb_perror_msg("error: no inet socket available"); 517 return -1; 518 } 519 520 for (;;) { 521 ifc.ifc_len = sizeof(struct ifreq) * numreqs; 522 ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len); 523 524 if (ioctl_or_warn(skfd, SIOCGIFCONF, &ifc) < 0) { 525 goto out; 526 } 527 if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) { 528 /* assume it overflowed and try again */ 529 numreqs += 10; 530 continue; 531 } 532 break; 533 } 534 535 ifr = ifc.ifc_req; 536 for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { 537 add_interface(ifr->ifr_name); 538 ifr++; 539 } 540 err = 0; 541 542 out: 543 close(skfd); 544 free(ifc.ifc_buf); 545 return err; 546 } 547 544 548 static int if_readlist_proc(char *target) 545 549 { 546 static int proc_read; 550 static smallint proc_read; 551 547 552 FILE *fh; 548 553 char buf[512]; … … 557 562 fh = fopen(_PATH_PROCNET_DEV, "r"); 558 563 if (!fh) { 559 bb_perror_msg(" Warning: cannot open %s. Limited output.", _PATH_PROCNET_DEV);564 bb_perror_msg("warning: cannot open %s, limiting output", _PATH_PROCNET_DEV); 560 565 return if_readconf(); 561 566 } … … 577 582 } 578 583 if (ferror(fh)) { 579 perror(_PATH_PROCNET_DEV);584 bb_perror_msg(_PATH_PROCNET_DEV); 580 585 err = -1; 581 586 proc_read = 0; … … 588 593 { 589 594 int err = if_readlist_proc(NULL); 590 595 /* Needed in order to get ethN:M aliases */ 591 596 if (!err) 592 597 err = if_readconf(); … … 594 599 } 595 600 596 static int for_all_interfaces(int (*doit) (struct interface *, void *),597 void *cookie)598 {599 struct interface *ife;600 601 if (!int_list && (if_readlist() < 0))602 return -1;603 for (ife = int_list; ife; ife = ife->next) {604 int err = doit(ife, cookie);605 606 if (err)607 return err;608 }609 return 0;610 }611 612 601 /* Fetch the interface configuration from the kernel. */ 613 602 static int if_fetch(struct interface *ife) 614 603 { 615 604 struct ifreq ifr; 616 int fd;617 605 char *ifname = ife->name; 618 619 strcpy(ifr.ifr_name, ifname); 620 if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) 621 return (-1); 606 int skfd; 607 608 skfd = xsocket(AF_INET, SOCK_DGRAM, 0); 609 610 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 611 if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) { 612 close(skfd); 613 return -1; 614 } 622 615 ife->flags = ifr.ifr_flags; 623 616 624 strcpy(ifr.ifr_name, ifname); 625 if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) 626 memset(ife->hwaddr, 0, 32); 627 else 617 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 618 memset(ife->hwaddr, 0, 32); 619 if (ioctl(skfd, SIOCGIFHWADDR, &ifr) >= 0) 628 620 memcpy(ife->hwaddr, ifr.ifr_hwaddr.sa_data, 8); 629 621 630 622 ife->type = ifr.ifr_hwaddr.sa_family; 631 623 632 strcpy(ifr.ifr_name, ifname); 633 if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) 634 ife->metric = 0; 635 else 624 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 625 ife->metric = 0; 626 if (ioctl(skfd, SIOCGIFMETRIC, &ifr) >= 0) 636 627 ife->metric = ifr.ifr_metric; 637 628 638 strcpy(ifr.ifr_name, ifname); 639 if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) 640 ife->mtu = 0; 641 else 629 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 630 ife->mtu = 0; 631 if (ioctl(skfd, SIOCGIFMTU, &ifr) >= 0) 642 632 ife->mtu = ifr.ifr_mtu; 643 633 634 memset(&ife->map, 0, sizeof(struct ifmap)); 644 635 #ifdef SIOCGIFMAP 645 str cpy(ifr.ifr_name, ifname);636 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 646 637 if (ioctl(skfd, SIOCGIFMAP, &ifr) == 0) 647 638 ife->map = ifr.ifr_map; 648 else 649 #endif 650 memset(&ife->map, 0, sizeof(struct ifmap)); 639 #endif 651 640 652 641 #ifdef HAVE_TXQUEUELEN 653 strcpy(ifr.ifr_name, ifname); 654 if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) < 0) 655 ife->tx_queue_len = -1; /* unknown value */ 656 else 642 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 643 ife->tx_queue_len = -1; /* unknown value */ 644 if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) >= 0) 657 645 ife->tx_queue_len = ifr.ifr_qlen; 658 646 #else … … 660 648 #endif 661 649 662 /* IPv4 address? */ 663 fd = get_socket_for_af(AF_INET); 664 if (fd >= 0) { 665 strcpy(ifr.ifr_name, ifname); 666 ifr.ifr_addr.sa_family = AF_INET; 667 if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) { 668 ife->has_ip = 1; 669 ife->addr = ifr.ifr_addr; 670 strcpy(ifr.ifr_name, ifname); 671 if (ioctl(fd, SIOCGIFDSTADDR, &ifr) < 0) 672 memset(&ife->dstaddr, 0, sizeof(struct sockaddr)); 673 else 674 ife->dstaddr = ifr.ifr_dstaddr; 675 676 strcpy(ifr.ifr_name, ifname); 677 if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0) 678 memset(&ife->broadaddr, 0, sizeof(struct sockaddr)); 679 else 680 ife->broadaddr = ifr.ifr_broadaddr; 681 682 strcpy(ifr.ifr_name, ifname); 683 if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) 684 memset(&ife->netmask, 0, sizeof(struct sockaddr)); 685 else 686 ife->netmask = ifr.ifr_netmask; 687 } else 688 memset(&ife->addr, 0, sizeof(struct sockaddr)); 689 } 690 650 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 651 ifr.ifr_addr.sa_family = AF_INET; 652 memset(&ife->addr, 0, sizeof(struct sockaddr)); 653 if (ioctl(skfd, SIOCGIFADDR, &ifr) == 0) { 654 ife->has_ip = 1; 655 ife->addr = ifr.ifr_addr; 656 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 657 memset(&ife->dstaddr, 0, sizeof(struct sockaddr)); 658 if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) >= 0) 659 ife->dstaddr = ifr.ifr_dstaddr; 660 661 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 662 memset(&ife->broadaddr, 0, sizeof(struct sockaddr)); 663 if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) >= 0) 664 ife->broadaddr = ifr.ifr_broadaddr; 665 666 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 667 memset(&ife->netmask, 0, sizeof(struct sockaddr)); 668 if (ioctl(skfd, SIOCGIFNETMASK, &ifr) >= 0) 669 ife->netmask = ifr.ifr_netmask; 670 } 671 672 close(skfd); 691 673 return 0; 692 674 } … … 696 678 { 697 679 if (if_fetch(ife) < 0) { 698 c har *errmsg;680 const char *errmsg; 699 681 700 682 if (errno == ENODEV) { … … 711 693 } 712 694 713 /* This structure defines hardware protocols and their handlers. */714 struct hwtype {715 const char * const name;716 const char *title;717 int type;718 int alen;719 char *(*print) (unsigned char *);720 int (*input) (char *, struct sockaddr *);721 int (*activate) (int fd);722 int suppress_null_addr;723 };724 725 695 static const struct hwtype unspec_hwtype = { 726 696 .name = "unspec", … … 738 708 #include <net/if_arp.h> 739 709 740 #if ( __GLIBC__ >=2 && __GLIBC_MINOR>= 1) || defined(_NEWLIB_VERSION)710 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION) 741 711 #include <net/ethernet.h> 742 712 #else … … 747 717 static char *pr_ether(unsigned char *ptr) 748 718 { 749 static char buff[64]; 750 751 snprintf(buff, sizeof(buff), "%02X:%02X:%02X:%02X:%02X:%02X", 719 static char *buff; 720 721 free(buff); 722 buff = xasprintf("%02X:%02X:%02X:%02X:%02X:%02X", 752 723 (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377), 753 724 (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377) 754 725 ); 755 return (buff); 756 } 726 return buff; 727 } 728 729 static int in_ether(const char *bufp, struct sockaddr *sap); 757 730 758 731 static const struct hwtype ether_hwtype = { … … 761 734 .type = ARPHRD_ETHER, 762 735 .alen = ETH_ALEN, 763 .print = pr_ether 764 }; 736 .print = pr_ether, 737 .input = in_ether 738 }; 739 740 static unsigned hexchar2int(char c) 741 { 742 if (isdigit(c)) 743 return c - '0'; 744 c &= ~0x20; /* a -> A */ 745 if ((unsigned)(c - 'A') <= 5) 746 return c - ('A' - 10); 747 return ~0U; 748 } 749 750 /* Input an Ethernet address and convert to binary. */ 751 static int in_ether(const char *bufp, struct sockaddr *sap) 752 { 753 unsigned char *ptr; 754 char c; 755 int i; 756 unsigned val; 757 758 sap->sa_family = ether_hwtype.type; 759 ptr = (unsigned char*) sap->sa_data; 760 761 i = 0; 762 while ((*bufp != '\0') && (i < ETH_ALEN)) { 763 val = hexchar2int(*bufp++) * 0x10; 764 if (val > 0xff) { 765 errno = EINVAL; 766 return -1; 767 } 768 c = *bufp; 769 if (c == ':' || c == 0) 770 val >>= 4; 771 else { 772 val |= hexchar2int(c); 773 if (val > 0xff) { 774 errno = EINVAL; 775 return -1; 776 } 777 } 778 if (c != 0) 779 bufp++; 780 *ptr++ = (unsigned char) val; 781 i++; 782 783 /* We might get a semicolon here - not required. */ 784 if (*bufp == ':') { 785 bufp++; 786 } 787 } 788 return 0; 789 } 765 790 766 791 #include <net/if_arp.h> … … 772 797 }; 773 798 774 #if def CONFIG_FEATURE_IPV6799 #if ENABLE_FEATURE_IPV6 775 800 static const struct hwtype sit_hwtype = { 776 801 .name = "sit", … … 779 804 .print = UNSPEC_print, 780 805 .suppress_null_addr = 1 781 } 782 #endif 783 784 static const struct hwtype * 806 }; 807 #endif 808 809 static const struct hwtype *const hwtypes[] = { 785 810 &loop_hwtype, 786 811 ðer_hwtype, 787 812 &ppp_hwtype, 788 813 &unspec_hwtype, 789 #if def CONFIG_FEATURE_IPV6814 #if ENABLE_FEATURE_IPV6 790 815 &sit_hwtype, 791 816 #endif … … 794 819 795 820 #ifdef IFF_PORTSEL 796 static const char * 821 static const char *const if_port_text[] = { 797 822 /* Keep in step with <linux/netdevice.h> */ 798 823 "unknown", … … 808 833 809 834 /* Check our hardware type table for this type. */ 810 static const struct hwtype *get_hwntype(int type) 811 { 812 const struct hwtype * const *hwp; 835 const struct hwtype *get_hwtype(const char *name) 836 { 837 const struct hwtype *const *hwp; 838 839 hwp = hwtypes; 840 while (*hwp != NULL) { 841 if (!strcmp((*hwp)->name, name)) 842 return (*hwp); 843 hwp++; 844 } 845 return NULL; 846 } 847 848 /* Check our hardware type table for this type. */ 849 const struct hwtype *get_hwntype(int type) 850 { 851 const struct hwtype *const *hwp; 813 852 814 853 hwp = hwtypes; 815 854 while (*hwp != NULL) { 816 855 if ((*hwp)->type == type) 817 return (*hwp);856 return *hwp; 818 857 hwp++; 819 858 } 820 return (NULL);859 return NULL; 821 860 } 822 861 … … 833 872 } 834 873 835 static const char TRext[] = "\0\0\0Ki\0Mi\0Gi\0Ti";874 static const char TRext[] ALIGN1 = "\0\0\0Ki\0Mi\0Gi\0Ti"; 836 875 837 876 static void print_bytes_scaled(unsigned long long ull, const char *end) … … 858 897 } 859 898 860 static const char * const ife_print_flags_strs[] = {861 "UP ",862 "BROADCAST ",863 "DEBUG ",864 "LOOPBACK ",865 "POINTOPOINT ",866 "NOTRAILERS ",867 "RUNNING ",868 "NOARP ",869 "PROMISC ",870 "ALLMULTI ",871 "SLAVE ",872 "MASTER ",873 "MULTICAST ",874 #ifdef HAVE_DYNAMIC875 "DYNAMIC "876 #endif877 };878 879 static const unsigned short ife_print_flags_mask[] = {880 IFF_UP,881 IFF_BROADCAST,882 IFF_DEBUG,883 IFF_LOOPBACK,884 IFF_POINTOPOINT,885 IFF_NOTRAILERS,886 IFF_RUNNING,887 IFF_NOARP,888 IFF_PROMISC,889 IFF_ALLMULTI,890 IFF_SLAVE,891 IFF_MASTER,892 IFF_MULTICAST,893 #ifdef HAVE_DYNAMIC894 IFF_DYNAMIC895 #endif896 0897 };898 899 899 static void ife_print(struct interface *ptr) 900 900 { 901 struct aftype *ap;901 const struct aftype *ap; 902 902 const struct hwtype *hw; 903 903 int hf; 904 904 int can_compress = 0; 905 905 906 #if HAVE_AFINET6906 #ifdef HAVE_AFINET6 907 907 FILE *f; 908 908 char addr6[40], devname[20]; … … 938 938 } 939 939 #endif 940 p rintf("\n");940 puts(""); 941 941 942 942 if (ptr->has_ip) { … … 952 952 } 953 953 954 #if HAVE_AFINET6954 #ifdef HAVE_AFINET6 955 955 956 956 #define IPV6_ADDR_ANY 0x0000U … … 971 971 #define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */ 972 972 973 if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) { 973 f = fopen(_PATH_PROCNET_IFINET6, "r"); 974 if (f != NULL) { 974 975 while (fscanf 975 (f, "%4s%4s%4s%4s%4s%4s%4s%4s %0 2x %02x %02x %02x %20s\n",976 (f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n", 976 977 addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], 977 978 addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, &scope, 978 &dad_status, devname) != EOF) { 979 &dad_status, devname) != EOF 980 ) { 979 981 if (!strcmp(devname, ptr->name)) { 980 982 sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", … … 985 987 sap.sin6_family = AF_INET6; 986 988 printf(" inet6 addr: %s/%d", 987 inet6_aftype.sprint((struct sockaddr *) &sap, 1),989 INET6_sprint((struct sockaddr *) &sap, 1), 988 990 plen); 989 991 printf(" Scope:"); 990 992 switch (scope & IPV6_ADDR_SCOPE_MASK) { 991 993 case 0: 992 p rintf("Global");994 puts("Global"); 993 995 break; 994 996 case IPV6_ADDR_LINKLOCAL: 995 p rintf("Link");997 puts("Link"); 996 998 break; 997 999 case IPV6_ADDR_SITELOCAL: 998 p rintf("Site");1000 puts("Site"); 999 1001 break; 1000 1002 case IPV6_ADDR_COMPATv4: 1001 p rintf("Compat");1003 puts("Compat"); 1002 1004 break; 1003 1005 case IPV6_ADDR_LOOPBACK: 1004 p rintf("Host");1006 puts("Host"); 1005 1007 break; 1006 1008 default: 1007 p rintf("Unknown");1009 puts("Unknown"); 1008 1010 } 1009 printf("\n");1010 1011 } 1011 1012 } … … 1020 1021 printf("[NO FLAGS] "); 1021 1022 } else { 1022 int i = 0; 1023 static const char ife_print_flags_strs[] ALIGN1 = 1024 "UP\0" 1025 "BROADCAST\0" 1026 "DEBUG\0" 1027 "LOOPBACK\0" 1028 "POINTOPOINT\0" 1029 "NOTRAILERS\0" 1030 "RUNNING\0" 1031 "NOARP\0" 1032 "PROMISC\0" 1033 "ALLMULTI\0" 1034 "SLAVE\0" 1035 "MASTER\0" 1036 "MULTICAST\0" 1037 #ifdef HAVE_DYNAMIC 1038 "DYNAMIC\0" 1039 #endif 1040 ; 1041 static const unsigned short ife_print_flags_mask[] ALIGN2 = { 1042 IFF_UP, 1043 IFF_BROADCAST, 1044 IFF_DEBUG, 1045 IFF_LOOPBACK, 1046 IFF_POINTOPOINT, 1047 IFF_NOTRAILERS, 1048 IFF_RUNNING, 1049 IFF_NOARP, 1050 IFF_PROMISC, 1051 IFF_ALLMULTI, 1052 IFF_SLAVE, 1053 IFF_MASTER, 1054 IFF_MULTICAST 1055 #ifdef HAVE_DYNAMIC 1056 ,IFF_DYNAMIC 1057 #endif 1058 }; 1059 const unsigned short *mask = ife_print_flags_mask; 1060 const char *str = ife_print_flags_strs; 1023 1061 do { 1024 if (ptr->flags & ife_print_flags_mask[i]) {1025 printf( ife_print_flags_strs[i]);1062 if (ptr->flags & *mask) { 1063 printf("%s ", str); 1026 1064 } 1027 } while (ife_print_flags_mask[++i]); 1065 mask++; 1066 str += strlen(str) + 1; 1067 } while (*str); 1028 1068 } 1029 1069 … … 1034 1074 printf(" Outfill:%d Keepalive:%d", ptr->outfill, ptr->keepalive); 1035 1075 #endif 1036 p rintf("\n");1076 puts(""); 1037 1077 1038 1078 /* If needed, display the interface statistics. */ … … 1083 1123 if (ptr->map.dma) 1084 1124 printf("DMA chan:%x ", ptr->map.dma); 1085 printf("\n"); 1086 } 1087 printf("\n"); 1088 } 1089 1090 1091 static int do_if_print(struct interface *ife, void *cookie) 1092 { 1093 int *opt_a = (int *) cookie; 1125 puts(""); 1126 } 1127 puts(""); 1128 } 1129 1130 1131 static int do_if_print(struct interface *ife) /*, int *opt_a)*/ 1132 { 1094 1133 int res; 1095 1134 1096 1135 res = do_if_fetch(ife); 1097 1136 if (res >= 0) { 1098 if ((ife->flags & IFF_UP) || *opt_a)1137 if ((ife->flags & IFF_UP) || interface_opt_a) 1099 1138 ife_print(ife); 1100 1139 } … … 1112 1151 } 1113 1152 1153 #ifdef UNUSED 1154 static int for_all_interfaces(int (*doit) (struct interface *, void *), 1155 void *cookie) 1156 { 1157 struct interface *ife; 1158 1159 if (!int_list && (if_readlist() < 0)) 1160 return -1; 1161 for (ife = int_list; ife; ife = ife->next) { 1162 int err = doit(ife, cookie); 1163 1164 if (err) 1165 return err; 1166 } 1167 return 0; 1168 } 1169 #endif 1170 1114 1171 /* for ipv4 add/del modes */ 1115 1172 static int if_print(char *ifname) 1116 1173 { 1174 struct interface *ife; 1117 1175 int res; 1118 1176 1119 1177 if (!ifname) { 1120 res = for_all_interfaces(do_if_print, &interface_opt_a); 1121 } else { 1122 struct interface *ife; 1123 1124 ife = lookup_interface(ifname); 1125 res = do_if_fetch(ife); 1126 if (res >= 0) 1127 ife_print(ife); 1128 } 1178 /*res = for_all_interfaces(do_if_print, &interface_opt_a);*/ 1179 if (!int_list && (if_readlist() < 0)) 1180 return -1; 1181 for (ife = int_list; ife; ife = ife->next) { 1182 int err = do_if_print(ife); /*, &interface_opt_a);*/ 1183 if (err) 1184 return err; 1185 } 1186 return 0; 1187 } 1188 ife = lookup_interface(ifname); 1189 res = do_if_fetch(ife); 1190 if (res >= 0) 1191 ife_print(ife); 1129 1192 return res; 1130 1193 } 1131 1194 1132 int display_interfaces(char *ifname);1133 1195 int display_interfaces(char *ifname) 1134 1196 { 1135 1197 int status; 1136 1198 1137 /* Create a channel to the NET kernel. */1138 if ((skfd = sockets_open(0)) < 0) {1139 bb_perror_msg_and_die("socket");1140 }1141 1142 /* Do we have to show the current setup? */1143 1199 status = if_print(ifname); 1144 #ifdef CONFIG_FEATURE_CLEAN_UP 1145 sockets_close(); 1146 #endif 1147 exit(status < 0); 1148 } 1200 1201 return (status < 0); /* status < 0 == 1 -- error */ 1202 }
Note:
See TracChangeset
for help on using the changeset viewer.