1 /* Code to manipulate interface information, shared between ifconfig and
4 10/1998 partly rewriten by Andi Kleen to support an interface list.
5 I don't claim that the list operations are efficient @).
7 8/2000 Andi Kleen make the list operations a bit more efficient.
8 People are crazy enough to use thousands of aliases now.
10 $Id: interface.c,v 1.25 2002/12/05 21:54:50 ecki Exp $
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <sys/ioctl.h>
18 #include <netinet/in.h>
28 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
29 #include <netipx/ipx.h>
36 #include <neteconet/ec.h>
40 #include <linux/if_slip.h>
41 #include <net/if_arp.h>
44 #include "net-support.h"
45 #include "pathnames.h"
49 #include "interface.h"
55 const char *if_port_text
[][4] =
57 /* Keep in step with <linux/netdevice.h> */
58 {"unknown", NULL
, NULL
, NULL
},
59 {"10base2", "bnc", "coax", NULL
},
60 {"10baseT", "utp", "tpe", NULL
},
61 {"AUI", "thick", "db15", NULL
},
62 {"100baseT", NULL
, NULL
, NULL
},
63 {"100baseTX", NULL
, NULL
, NULL
},
64 {"100baseFX", NULL
, NULL
, NULL
},
65 {NULL
, NULL
, NULL
, NULL
},
69 #define IPV6_ADDR_ANY 0x0000U
71 #define IPV6_ADDR_UNICAST 0x0001U
72 #define IPV6_ADDR_MULTICAST 0x0002U
73 #define IPV6_ADDR_ANYCAST 0x0004U
75 #define IPV6_ADDR_LOOPBACK 0x0010U
76 #define IPV6_ADDR_LINKLOCAL 0x0020U
77 #define IPV6_ADDR_SITELOCAL 0x0040U
79 #define IPV6_ADDR_COMPATv4 0x0080U
81 #define IPV6_ADDR_SCOPE_MASK 0x00f0U
83 #define IPV6_ADDR_MAPPED 0x1000U
84 #define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */
86 int procnetdev_vsn
= 1;
90 int if_list_all
= 0; /* do we have requested the complete proc list, yet? */
92 static struct interface
*int_list
, *int_last
;
94 static int if_readlist_proc(char *);
96 static struct interface
*if_cache_add(char *name
)
98 struct interface
*ife
, **nextp
, *new;
103 for (ife
= int_last
; ife
; ife
= ife
->prev
) {
104 int n
= nstrcmp(ife
->name
, name
);
111 safe_strncpy(new->name
, name
, IFNAMSIZ
);
112 nextp
= ife
? &ife
->next
: &int_list
;
116 new->next
->prev
= new;
123 struct interface
*lookup_interface(char *name
)
125 /* if we have read all, use it */
127 return if_cache_add(name
);
129 /* otherwise we read a limited list */
130 if (if_readlist_proc(name
) < 0)
133 return if_cache_add(name
);
136 int for_all_interfaces(int (*doit
) (struct interface
*, void *), void *cookie
)
138 struct interface
*ife
;
140 if (!int_list_all
&& (if_readlist() < 0))
142 for (ife
= int_list
; ife
; ife
= ife
->next
) {
143 int err
= doit(ife
, cookie
);
150 int if_cache_free(void)
152 struct interface
*ife
;
153 while ((ife
= int_list
) != NULL
) {
154 int_list
= ife
->next
;
162 static int if_readconf(void)
170 /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets
172 skfd
= get_socket_for_af(AF_INET
);
174 fprintf(stderr
, _("warning: no inet socket available: %s\n"),
176 /* Try to soldier on with whatever socket we can get hold of. */
177 skfd
= sockets_open(0);
184 ifc
.ifc_len
= sizeof(struct ifreq
) * numreqs
;
185 ifc
.ifc_buf
= xrealloc(ifc
.ifc_buf
, ifc
.ifc_len
);
187 if (ioctl(skfd
, SIOCGIFCONF
, &ifc
) < 0) {
188 perror("SIOCGIFCONF");
191 if (ifc
.ifc_len
== sizeof(struct ifreq
) * numreqs
) {
192 /* assume it overflowed and try again */
200 for (n
= 0; n
< ifc
.ifc_len
; n
+= sizeof(struct ifreq
)) {
201 if_cache_add(ifr
->ifr_name
);
211 char *get_name(char *name
, char *p
)
218 if (*p
== ':') { /* could be an alias */
220 while (*p
&& isdigit(*p
)) p
++;
222 /* Yes it is, backup and copy it. */
225 while (*p
&& isdigit(*p
)) {
241 int procnetdev_version(char *buf
)
243 if (strstr(buf
, "compressed"))
245 if (strstr(buf
, "bytes"))
250 int get_dev_fields(char *bp
, struct interface
*ife
)
252 switch (procnetdev_vsn
) {
255 "%Lu %Lu %lu %lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu %lu",
256 &ife
->stats
.rx_bytes
,
257 &ife
->stats
.rx_packets
,
258 &ife
->stats
.rx_errors
,
259 &ife
->stats
.rx_dropped
,
260 &ife
->stats
.rx_fifo_errors
,
261 &ife
->stats
.rx_frame_errors
,
262 &ife
->stats
.rx_compressed
,
263 &ife
->stats
.rx_multicast
,
265 &ife
->stats
.tx_bytes
,
266 &ife
->stats
.tx_packets
,
267 &ife
->stats
.tx_errors
,
268 &ife
->stats
.tx_dropped
,
269 &ife
->stats
.tx_fifo_errors
,
270 &ife
->stats
.collisions
,
271 &ife
->stats
.tx_carrier_errors
,
272 &ife
->stats
.tx_compressed
);
275 sscanf(bp
, "%Lu %Lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu",
276 &ife
->stats
.rx_bytes
,
277 &ife
->stats
.rx_packets
,
278 &ife
->stats
.rx_errors
,
279 &ife
->stats
.rx_dropped
,
280 &ife
->stats
.rx_fifo_errors
,
281 &ife
->stats
.rx_frame_errors
,
283 &ife
->stats
.tx_bytes
,
284 &ife
->stats
.tx_packets
,
285 &ife
->stats
.tx_errors
,
286 &ife
->stats
.tx_dropped
,
287 &ife
->stats
.tx_fifo_errors
,
288 &ife
->stats
.collisions
,
289 &ife
->stats
.tx_carrier_errors
);
290 ife
->stats
.rx_multicast
= 0;
293 sscanf(bp
, "%Lu %lu %lu %lu %lu %Lu %lu %lu %lu %lu %lu",
294 &ife
->stats
.rx_packets
,
295 &ife
->stats
.rx_errors
,
296 &ife
->stats
.rx_dropped
,
297 &ife
->stats
.rx_fifo_errors
,
298 &ife
->stats
.rx_frame_errors
,
300 &ife
->stats
.tx_packets
,
301 &ife
->stats
.tx_errors
,
302 &ife
->stats
.tx_dropped
,
303 &ife
->stats
.tx_fifo_errors
,
304 &ife
->stats
.collisions
,
305 &ife
->stats
.tx_carrier_errors
);
306 ife
->stats
.rx_bytes
= 0;
307 ife
->stats
.tx_bytes
= 0;
308 ife
->stats
.rx_multicast
= 0;
314 static int if_readlist_proc(char *target
)
318 struct interface
*ife
;
321 fh
= fopen(_PATH_PROCNET_DEV
, "r");
323 fprintf(stderr
, _("Warning: cannot open %s (%s). Limited output.\n"),
324 _PATH_PROCNET_DEV
, strerror(errno
));
327 fgets(buf
, sizeof buf
, fh
); /* eat line */
328 fgets(buf
, sizeof buf
, fh
);
330 #if 0 /* pretty, but can't cope with missing fields */
331 fmt
= proc_gen_fmt(_PATH_PROCNET_DEV
, 1, fh
,
332 "face", "", /* parsed separately */
353 procnetdev_vsn
= procnetdev_version(buf
);
357 while (fgets(buf
, sizeof buf
, fh
)) {
358 char *s
, name
[IFNAMSIZ
];
359 s
= get_name(name
, buf
);
360 ife
= if_cache_add(name
);
361 get_dev_fields(s
, ife
);
362 ife
->statistics_valid
= 1;
363 if (target
&& !strcmp(target
,name
))
367 perror(_PATH_PROCNET_DEV
);
378 int if_readlist(void)
380 /* caller will/should check not to call this too often
381 * (i.e. only if int_list_all == 0
383 int err
= if_readlist_proc(NULL
);
394 /* Support for fetching an IPX address */
397 static int ipx_getaddr(int sock
, int ft
, struct ifreq
*ifr
)
399 ((struct sockaddr_ipx
*) &ifr
->ifr_addr
)->sipx_type
= ft
;
400 return ioctl(sock
, SIOCGIFADDR
, ifr
);
404 /* Fetch the interface configuration from the kernel. */
405 int if_fetch(struct interface
*ife
)
409 char *ifname
= ife
->name
;
411 strcpy(ifr
.ifr_name
, ifname
);
412 if (ioctl(skfd
, SIOCGIFFLAGS
, &ifr
) < 0)
414 ife
->flags
= ifr
.ifr_flags
;
416 strcpy(ifr
.ifr_name
, ifname
);
417 if (ioctl(skfd
, SIOCGIFHWADDR
, &ifr
) < 0)
418 memset(ife
->hwaddr
, 0, 32);
420 memcpy(ife
->hwaddr
, ifr
.ifr_hwaddr
.sa_data
, 8);
422 ife
->type
= ifr
.ifr_hwaddr
.sa_family
;
424 strcpy(ifr
.ifr_name
, ifname
);
425 if (ioctl(skfd
, SIOCGIFMETRIC
, &ifr
) < 0)
428 ife
->metric
= ifr
.ifr_metric
;
430 strcpy(ifr
.ifr_name
, ifname
);
431 if (ioctl(skfd
, SIOCGIFMTU
, &ifr
) < 0)
434 ife
->mtu
= ifr
.ifr_mtu
;
437 if (ife
->type
== ARPHRD_SLIP
|| ife
->type
== ARPHRD_CSLIP
||
438 ife
->type
== ARPHRD_SLIP6
|| ife
->type
== ARPHRD_CSLIP6
||
439 ife
->type
== ARPHRD_ADAPT
) {
441 strcpy(ifr
.ifr_name
, ifname
);
442 if (ioctl(skfd
, SIOCGOUTFILL
, &ifr
) < 0)
445 ife
->outfill
= (unsigned int) ifr
.ifr_data
;
447 #ifdef SIOCGKEEPALIVE
448 strcpy(ifr
.ifr_name
, ifname
);
449 if (ioctl(skfd
, SIOCGKEEPALIVE
, &ifr
) < 0)
452 ife
->keepalive
= (unsigned int) ifr
.ifr_data
;
457 strcpy(ifr
.ifr_name
, ifname
);
458 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0)
459 memset(&ife
->map
, 0, sizeof(struct ifmap
));
461 memcpy(&ife
->map
, &ifr
.ifr_map
, sizeof(struct ifmap
));
463 strcpy(ifr
.ifr_name
, ifname
);
464 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0)
465 memset(&ife
->map
, 0, sizeof(struct ifmap
));
467 ife
->map
= ifr
.ifr_map
;
469 #ifdef HAVE_TXQUEUELEN
470 strcpy(ifr
.ifr_name
, ifname
);
471 if (ioctl(skfd
, SIOCGIFTXQLEN
, &ifr
) < 0)
472 ife
->tx_queue_len
= -1; /* unknown value */
474 ife
->tx_queue_len
= ifr
.ifr_qlen
;
476 ife
->tx_queue_len
= -1; /* unknown value */
481 fd
= get_socket_for_af(AF_INET
);
483 strcpy(ifr
.ifr_name
, ifname
);
484 ifr
.ifr_addr
.sa_family
= AF_INET
;
485 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
487 ife
->addr
= ifr
.ifr_addr
;
488 strcpy(ifr
.ifr_name
, ifname
);
489 if (ioctl(fd
, SIOCGIFDSTADDR
, &ifr
) < 0)
490 memset(&ife
->dstaddr
, 0, sizeof(struct sockaddr
));
492 ife
->dstaddr
= ifr
.ifr_dstaddr
;
494 strcpy(ifr
.ifr_name
, ifname
);
495 if (ioctl(fd
, SIOCGIFBRDADDR
, &ifr
) < 0)
496 memset(&ife
->broadaddr
, 0, sizeof(struct sockaddr
));
498 ife
->broadaddr
= ifr
.ifr_broadaddr
;
500 strcpy(ifr
.ifr_name
, ifname
);
501 if (ioctl(fd
, SIOCGIFNETMASK
, &ifr
) < 0)
502 memset(&ife
->netmask
, 0, sizeof(struct sockaddr
));
504 ife
->netmask
= ifr
.ifr_netmask
;
506 memset(&ife
->addr
, 0, sizeof(struct sockaddr
));
511 /* DDP address maybe ? */
512 fd
= get_socket_for_af(AF_APPLETALK
);
514 strcpy(ifr
.ifr_name
, ifname
);
515 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
516 ife
->ddpaddr
= ifr
.ifr_addr
;
523 /* Look for IPX addresses with all framing types */
524 fd
= get_socket_for_af(AF_IPX
);
526 strcpy(ifr
.ifr_name
, ifname
);
527 if (!ipx_getaddr(fd
, IPX_FRAME_ETHERII
, &ifr
)) {
529 ife
->ipxaddr_bb
= ifr
.ifr_addr
;
531 strcpy(ifr
.ifr_name
, ifname
);
532 if (!ipx_getaddr(fd
, IPX_FRAME_SNAP
, &ifr
)) {
534 ife
->ipxaddr_sn
= ifr
.ifr_addr
;
536 strcpy(ifr
.ifr_name
, ifname
);
537 if (!ipx_getaddr(fd
, IPX_FRAME_8023
, &ifr
)) {
539 ife
->ipxaddr_e3
= ifr
.ifr_addr
;
541 strcpy(ifr
.ifr_name
, ifname
);
542 if (!ipx_getaddr(fd
, IPX_FRAME_8022
, &ifr
)) {
544 ife
->ipxaddr_e2
= ifr
.ifr_addr
;
550 /* Econet address maybe? */
551 fd
= get_socket_for_af(AF_ECONET
);
553 strcpy(ifr
.ifr_name
, ifname
);
554 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
555 ife
->ecaddr
= ifr
.ifr_addr
;
564 int do_if_fetch(struct interface
*ife
)
566 if (if_fetch(ife
) < 0) {
568 if (errno
== ENODEV
) {
569 /* Give better error message for this case. */
570 errmsg
= _("Device not found");
572 errmsg
= strerror(errno
);
574 fprintf(stderr
, _("%s: error fetching interface information: %s\n"),
581 int do_if_print(struct interface
*ife
, void *cookie
)
583 int *opt_a
= (int *) cookie
;
586 res
= do_if_fetch(ife
);
588 if ((ife
->flags
& IFF_UP
) || *opt_a
)
594 void ife_print_short(struct interface
*ptr
)
596 printf("%-5.5s ", ptr
->name
);
597 printf("%5d %-2d", ptr
->mtu
, ptr
->metric
);
598 /* If needed, display the interface statistics. */
599 if (ptr
->statistics_valid
) {
600 printf("%9llu %6lu %6lu %-5lu",
601 ptr
->stats
.rx_packets
, ptr
->stats
.rx_errors
,
602 ptr
->stats
.rx_dropped
, ptr
->stats
.rx_fifo_errors
);
603 printf("%9llu %6lu %6lu %6lu ",
604 ptr
->stats
.tx_packets
, ptr
->stats
.tx_errors
,
605 ptr
->stats
.tx_dropped
, ptr
->stats
.tx_fifo_errors
);
607 printf("%-56s", _(" - no statistics available -"));
609 /* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
611 printf(_("[NO FLAGS]"));
612 if (ptr
->flags
& IFF_ALLMULTI
)
614 if (ptr
->flags
& IFF_BROADCAST
)
616 if (ptr
->flags
& IFF_DEBUG
)
618 if (ptr
->flags
& IFF_LOOPBACK
)
620 if (ptr
->flags
& IFF_MULTICAST
)
623 if (ptr
->flags
& IFF_DYNAMIC
)
626 if (ptr
->flags
& IFF_PROMISC
)
628 if (ptr
->flags
& IFF_NOTRAILERS
)
630 if (ptr
->flags
& IFF_NOARP
)
632 if (ptr
->flags
& IFF_POINTOPOINT
)
634 if (ptr
->flags
& IFF_SLAVE
)
636 if (ptr
->flags
& IFF_MASTER
)
638 if (ptr
->flags
& IFF_RUNNING
)
640 if (ptr
->flags
& IFF_UP
)
642 /* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
646 void ife_print_long(struct interface
*ptr
)
651 int can_compress
= 0;
652 unsigned long long rx
, tx
, short_rx
, short_tx
;
653 const char *Rext
= "b";
654 const char *Text
= "b";
657 static struct aftype
*ipxtype
= NULL
;
660 static struct aftype
*ectype
= NULL
;
663 static struct aftype
*ddptype
= NULL
;
667 char addr6
[40], devname
[20];
668 struct sockaddr_in6 sap
;
669 int plen
, scope
, dad_status
, if_idx
;
670 extern struct aftype inet6_aftype
;
674 ap
= get_afntype(ptr
->addr
.sa_family
);
680 if (hf
== ARPHRD_CSLIP
|| hf
== ARPHRD_CSLIP6
)
683 hw
= get_hwntype(hf
);
685 hw
= get_hwntype(-1);
687 printf(_("%-9.9s Link encap:%s "), ptr
->name
, hw
->title
);
688 /* For some hardware types (eg Ash, ATM) we don't print the
689 hardware address if it's null. */
690 if (hw
->print
!= NULL
&& (! (hw_null_address(hw
, ptr
->hwaddr
) &&
691 hw
->suppress_null_addr
)))
692 printf(_("HWaddr %s "), hw
->print(ptr
->hwaddr
));
694 if (ptr
->flags
& IFF_PORTSEL
) {
695 printf(_("Media:%s"), if_port_text
[ptr
->map
.port
][0]);
696 if (ptr
->flags
& IFF_AUTOMEDIA
)
704 printf(_(" %s addr:%s "), ap
->name
,
705 ap
->sprint(&ptr
->addr
, 1));
706 if (ptr
->flags
& IFF_POINTOPOINT
) {
707 printf(_(" P-t-P:%s "), ap
->sprint(&ptr
->dstaddr
, 1));
709 if (ptr
->flags
& IFF_BROADCAST
) {
710 printf(_(" Bcast:%s "), ap
->sprint(&ptr
->broadaddr
, 1));
712 printf(_(" Mask:%s\n"), ap
->sprint(&ptr
->netmask
, 1));
717 /* FIXME: should be integrated into interface.c. */
719 if ((f
= fopen(_PATH_PROCNET_IFINET6
, "r")) != NULL
) {
720 while (fscanf(f
, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
721 addr6p
[0], addr6p
[1], addr6p
[2], addr6p
[3],
722 addr6p
[4], addr6p
[5], addr6p
[6], addr6p
[7],
723 &if_idx
, &plen
, &scope
, &dad_status
, devname
) != EOF
) {
724 if (!strcmp(devname
, ptr
->name
)) {
725 sprintf(addr6
, "%s:%s:%s:%s:%s:%s:%s:%s",
726 addr6p
[0], addr6p
[1], addr6p
[2], addr6p
[3],
727 addr6p
[4], addr6p
[5], addr6p
[6], addr6p
[7]);
728 inet6_aftype
.input(1, addr6
, (struct sockaddr
*) &sap
);
729 printf(_(" inet6 addr: %s/%d"),
730 inet6_aftype
.sprint((struct sockaddr
*) &sap
, 1), plen
);
731 printf(_(" Scope:"));
736 case IPV6_ADDR_LINKLOCAL
:
739 case IPV6_ADDR_SITELOCAL
:
742 case IPV6_ADDR_COMPATv4
:
745 case IPV6_ADDR_LOOPBACK
:
749 printf(_("Unknown"));
760 ipxtype
= get_afntype(AF_IPX
);
762 if (ipxtype
!= NULL
) {
764 printf(_(" IPX/Ethernet II addr:%s\n"),
765 ipxtype
->sprint(&ptr
->ipxaddr_bb
, 1));
767 printf(_(" IPX/Ethernet SNAP addr:%s\n"),
768 ipxtype
->sprint(&ptr
->ipxaddr_sn
, 1));
770 printf(_(" IPX/Ethernet 802.2 addr:%s\n"),
771 ipxtype
->sprint(&ptr
->ipxaddr_e2
, 1));
773 printf(_(" IPX/Ethernet 802.3 addr:%s\n"),
774 ipxtype
->sprint(&ptr
->ipxaddr_e3
, 1));
780 ddptype
= get_afntype(AF_APPLETALK
);
781 if (ddptype
!= NULL
) {
783 printf(_(" EtherTalk Phase 2 addr:%s\n"), ddptype
->sprint(&ptr
->ddpaddr
, 1));
789 ectype
= get_afntype(AF_ECONET
);
790 if (ectype
!= NULL
) {
792 printf(_(" econet addr:%s\n"), ectype
->sprint(&ptr
->ecaddr
, 1));
797 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */
799 printf(_("[NO FLAGS] "));
800 if (ptr
->flags
& IFF_UP
)
802 if (ptr
->flags
& IFF_BROADCAST
)
803 printf(_("BROADCAST "));
804 if (ptr
->flags
& IFF_DEBUG
)
806 if (ptr
->flags
& IFF_LOOPBACK
)
807 printf(_("LOOPBACK "));
808 if (ptr
->flags
& IFF_POINTOPOINT
)
809 printf(_("POINTOPOINT "));
810 if (ptr
->flags
& IFF_NOTRAILERS
)
811 printf(_("NOTRAILERS "));
812 if (ptr
->flags
& IFF_RUNNING
)
813 printf(_("RUNNING "));
814 if (ptr
->flags
& IFF_NOARP
)
816 if (ptr
->flags
& IFF_PROMISC
)
817 printf(_("PROMISC "));
818 if (ptr
->flags
& IFF_ALLMULTI
)
819 printf(_("ALLMULTI "));
820 if (ptr
->flags
& IFF_SLAVE
)
822 if (ptr
->flags
& IFF_MASTER
)
823 printf(_("MASTER "));
824 if (ptr
->flags
& IFF_MULTICAST
)
825 printf(_("MULTICAST "));
827 if (ptr
->flags
& IFF_DYNAMIC
)
828 printf(_("DYNAMIC "));
830 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short */
831 printf(_(" MTU:%d Metric:%d"),
832 ptr
->mtu
, ptr
->metric
? ptr
->metric
: 1);
833 #ifdef SIOCSKEEPALIVE
834 if (ptr
->outfill
|| ptr
->keepalive
)
835 printf(_(" Outfill:%d Keepalive:%d"),
836 ptr
->outfill
, ptr
->keepalive
);
840 /* If needed, display the interface statistics. */
842 if (ptr
->statistics_valid
) {
843 /* XXX: statistics are currently only printed for the primary address,
844 * not for the aliases, although strictly speaking they're shared
849 printf(_("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
850 ptr
->stats
.rx_packets
, ptr
->stats
.rx_errors
,
851 ptr
->stats
.rx_dropped
, ptr
->stats
.rx_fifo_errors
,
852 ptr
->stats
.rx_frame_errors
);
854 printf(_(" compressed:%lu\n"), ptr
->stats
.rx_compressed
);
856 rx
= ptr
->stats
.rx_bytes
;
857 tx
= ptr
->stats
.tx_bytes
;
860 if (rx
> 1125899906842624) {
861 short_rx
/= 1125899906842624;
863 } else if (rx
> 1099511627776) {
864 short_rx
/= 1099511627776;
866 } else if (rx
> 1073741824) {
867 short_rx
/= 1073741824;
869 } else if (rx
> 1048576) {
872 } else if (rx
> 1024) {
876 if (tx
> 1125899906842624) {
877 short_tx
/= 1125899906842624;
879 } else if (tx
> 1099511627776) {
880 short_tx
/= 1099511627776;
882 } else if (tx
> 1073741824) {
883 short_tx
/= 1073741824;
885 } else if (tx
> 1048576) {
888 } else if (tx
> 1024) {
894 printf(_("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"),
895 ptr
->stats
.tx_packets
, ptr
->stats
.tx_errors
,
896 ptr
->stats
.tx_dropped
, ptr
->stats
.tx_fifo_errors
,
897 ptr
->stats
.tx_carrier_errors
);
898 printf(_(" collisions:%lu "), ptr
->stats
.collisions
);
900 printf(_("compressed:%lu "), ptr
->stats
.tx_compressed
);
901 if (ptr
->tx_queue_len
!= -1)
902 printf(_("txqueuelen:%d "), ptr
->tx_queue_len
);
904 printf(_("RX bytes:%llu (%lu.%lu %s) TX bytes:%llu (%lu.%lu %s)\n"),
905 rx
, (unsigned long)(short_rx
/ 10),
906 (unsigned long)(short_rx
% 10), Rext
,
907 tx
, (unsigned long)(short_tx
/ 10),
908 (unsigned long)(short_tx
% 10), Text
);
911 if ((ptr
->map
.irq
|| ptr
->map
.mem_start
|| ptr
->map
.dma
||
912 ptr
->map
.base_addr
>= 0x100)) {
915 printf(_("Interrupt:%d "), ptr
->map
.irq
);
916 if (ptr
->map
.base_addr
>= 0x100) /* Only print devices using it for
918 printf(_("Base address:0x%x "), ptr
->map
.base_addr
);
919 if (ptr
->map
.mem_start
) {
920 printf(_("Memory:%lx-%lx "), ptr
->map
.mem_start
, ptr
->map
.mem_end
);
923 printf(_("DMA chan:%x "), ptr
->map
.dma
);
929 void ife_print(struct interface
*i
)