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.1.2.3 2007/04/14 18:07:42 marschap Exp $
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <sys/ioctl.h>
18 #include <netinet/in.h>
29 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
30 #include <netipx/ipx.h>
37 #include <neteconet/ec.h>
41 #include <linux/if_slip.h>
42 #include <net/if_arp.h>
45 #include "net-support.h"
46 #include "pathnames.h"
50 #include "interface.h"
56 const char *if_port_text
[][4] =
58 /* Keep in step with <linux/netdevice.h> */
59 {"unknown", NULL
, NULL
, NULL
},
60 {"10base2", "bnc", "coax", NULL
},
61 {"10baseT", "utp", "tpe", NULL
},
62 {"AUI", "thick", "db15", NULL
},
63 {"100baseT", NULL
, NULL
, NULL
},
64 {"100baseTX", NULL
, NULL
, NULL
},
65 {"100baseFX", NULL
, NULL
, NULL
},
66 {NULL
, NULL
, NULL
, NULL
},
70 #define IPV6_ADDR_ANY 0x0000U
72 #define IPV6_ADDR_UNICAST 0x0001U
73 #define IPV6_ADDR_MULTICAST 0x0002U
74 #define IPV6_ADDR_ANYCAST 0x0004U
76 #define IPV6_ADDR_LOOPBACK 0x0010U
77 #define IPV6_ADDR_LINKLOCAL 0x0020U
78 #define IPV6_ADDR_SITELOCAL 0x0040U
80 #define IPV6_ADDR_COMPATv4 0x0080U
82 #define IPV6_ADDR_SCOPE_MASK 0x00f0U
84 #define IPV6_ADDR_MAPPED 0x1000U
85 #define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */
87 int procnetdev_vsn
= 1;
91 int if_list_all
= 0; /* do we have requested the complete proc list, yet? */
93 static struct interface
*int_list
, *int_last
;
95 static int if_readlist_proc(char *);
97 static struct interface
*if_cache_add(char *name
)
99 struct interface
*ife
, **nextp
, *new;
104 /* the cache is sorted, so if we hit a smaller if, exit */
105 for (ife
= int_last
; ife
; ife
= ife
->prev
) {
106 int n
= nstrcmp(ife
->name
, name
);
113 safe_strncpy(new->name
, name
, IFNAMSIZ
);
114 nextp
= ife
? &ife
->next
: &int_list
; // keep sorting
118 new->next
->prev
= new;
125 struct interface
*lookup_interface(char *name
)
127 /* if we have read all, use it */
129 return if_cache_add(name
);
131 /* otherwise we read a limited list */
132 if (if_readlist_proc(name
) < 0)
135 return if_cache_add(name
);
138 int for_all_interfaces(int SD
, int (*doit
) (int, struct interface
*, void *), void *cookie
)
140 struct interface
*ife
;
142 if (!if_list_all
&& (if_readlist() < 0))
144 for (ife
= int_list
; ife
; ife
= ife
->next
) {
145 int err
= doit(SD
, ife
, cookie
);
152 int if_cache_free(void)
154 struct interface
*ife
;
155 while ((ife
= int_list
) != NULL
) {
156 int_list
= ife
->next
;
164 static int if_readconf(void)
172 /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets
174 skfd
= get_socket_for_af(AF_INET
);
176 fprintf(stderr
, _("warning: no inet socket available: %s\n"),
178 /* Try to soldier on with whatever socket we can get hold of. */
179 skfd
= sockets_open(0);
186 ifc
.ifc_len
= sizeof(struct ifreq
) * numreqs
;
187 ifc
.ifc_buf
= xrealloc(ifc
.ifc_buf
, ifc
.ifc_len
);
189 if (ioctl(skfd
, SIOCGIFCONF
, &ifc
) < 0) {
190 perror("SIOCGIFCONF");
193 if (ifc
.ifc_len
== sizeof(struct ifreq
) * numreqs
) {
194 /* assume it overflowed and try again */
202 for (n
= 0; n
< ifc
.ifc_len
; n
+= sizeof(struct ifreq
)) {
203 if_cache_add(ifr
->ifr_name
);
213 char *get_name(char *name
, char *p
)
220 if (*p
== ':') { /* could be an alias */
222 while (*p
&& isdigit(*p
)) p
++;
224 /* Yes it is, backup and copy it. */
227 while (*p
&& isdigit(*p
)) {
243 int procnetdev_version(char *buf
)
245 if (strstr(buf
, "compressed"))
247 if (strstr(buf
, "bytes"))
252 int get_dev_fields(char *bp
, struct interface
*ife
)
254 switch (procnetdev_vsn
) {
257 "%Lu %Lu %lu %lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu %lu",
258 &ife
->stats
.rx_bytes
,
259 &ife
->stats
.rx_packets
,
260 &ife
->stats
.rx_errors
,
261 &ife
->stats
.rx_dropped
,
262 &ife
->stats
.rx_fifo_errors
,
263 &ife
->stats
.rx_frame_errors
,
264 &ife
->stats
.rx_compressed
,
265 &ife
->stats
.rx_multicast
,
267 &ife
->stats
.tx_bytes
,
268 &ife
->stats
.tx_packets
,
269 &ife
->stats
.tx_errors
,
270 &ife
->stats
.tx_dropped
,
271 &ife
->stats
.tx_fifo_errors
,
272 &ife
->stats
.collisions
,
273 &ife
->stats
.tx_carrier_errors
,
274 &ife
->stats
.tx_compressed
);
277 sscanf(bp
, "%Lu %Lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu",
278 &ife
->stats
.rx_bytes
,
279 &ife
->stats
.rx_packets
,
280 &ife
->stats
.rx_errors
,
281 &ife
->stats
.rx_dropped
,
282 &ife
->stats
.rx_fifo_errors
,
283 &ife
->stats
.rx_frame_errors
,
285 &ife
->stats
.tx_bytes
,
286 &ife
->stats
.tx_packets
,
287 &ife
->stats
.tx_errors
,
288 &ife
->stats
.tx_dropped
,
289 &ife
->stats
.tx_fifo_errors
,
290 &ife
->stats
.collisions
,
291 &ife
->stats
.tx_carrier_errors
);
292 ife
->stats
.rx_multicast
= 0;
295 sscanf(bp
, "%Lu %lu %lu %lu %lu %Lu %lu %lu %lu %lu %lu",
296 &ife
->stats
.rx_packets
,
297 &ife
->stats
.rx_errors
,
298 &ife
->stats
.rx_dropped
,
299 &ife
->stats
.rx_fifo_errors
,
300 &ife
->stats
.rx_frame_errors
,
302 &ife
->stats
.tx_packets
,
303 &ife
->stats
.tx_errors
,
304 &ife
->stats
.tx_dropped
,
305 &ife
->stats
.tx_fifo_errors
,
306 &ife
->stats
.collisions
,
307 &ife
->stats
.tx_carrier_errors
);
308 ife
->stats
.rx_bytes
= 0;
309 ife
->stats
.tx_bytes
= 0;
310 ife
->stats
.rx_multicast
= 0;
316 static int if_readlist_proc(char *target
)
320 struct interface
*ife
;
323 fh
= fopen(_PATH_PROCNET_DEV
, "r");
325 fprintf(stderr
, _("Warning: cannot open %s (%s). Limited output.\n"),
326 _PATH_PROCNET_DEV
, strerror(errno
));
329 fgets(buf
, sizeof buf
, fh
); /* eat line */
330 fgets(buf
, sizeof buf
, fh
);
332 #if 0 /* pretty, but can't cope with missing fields */
333 fmt
= proc_gen_fmt(_PATH_PROCNET_DEV
, 1, fh
,
334 "face", "", /* parsed separately */
355 procnetdev_vsn
= procnetdev_version(buf
);
359 while (fgets(buf
, sizeof buf
, fh
)) {
360 char *s
, name
[IFNAMSIZ
];
361 s
= get_name(name
, buf
);
362 ife
= if_cache_add(name
);
363 get_dev_fields(s
, ife
);
364 ife
->statistics_valid
= 1;
365 if (target
&& !strcmp(target
,name
))
369 perror(_PATH_PROCNET_DEV
);
380 int if_readlist(void)
382 /* caller will/should check not to call this too often
383 * (i.e. only if if_list_all == 0
387 err
|= if_readlist_proc(NULL
);
388 err
|= if_readconf();
395 /* Support for fetching an IPX address */
398 static int ipx_getaddr(int sock
, int ft
, struct ifreq
*ifr
)
400 ((struct sockaddr_ipx
*) &ifr
->ifr_addr
)->sipx_type
= ft
;
401 return ioctl(sock
, SIOCGIFADDR
, ifr
);
405 /* Fetch the interface configuration from the kernel. */
406 int if_fetch(struct interface
*ife
)
410 char *ifname
= ife
->name
;
412 strcpy(ifr
.ifr_name
, ifname
);
413 if (ioctl(skfd
, SIOCGIFFLAGS
, &ifr
) < 0)
415 ife
->flags
= ifr
.ifr_flags
;
417 strcpy(ifr
.ifr_name
, ifname
);
418 if (ioctl(skfd
, SIOCGIFHWADDR
, &ifr
) < 0)
419 memset(ife
->hwaddr
, 0, 32);
421 memcpy(ife
->hwaddr
, ifr
.ifr_hwaddr
.sa_data
, 8);
423 ife
->type
= ifr
.ifr_hwaddr
.sa_family
;
425 strcpy(ifr
.ifr_name
, ifname
);
426 if (ioctl(skfd
, SIOCGIFMETRIC
, &ifr
) < 0)
429 ife
->metric
= ifr
.ifr_metric
;
431 strcpy(ifr
.ifr_name
, ifname
);
432 if (ioctl(skfd
, SIOCGIFMTU
, &ifr
) < 0)
435 ife
->mtu
= ifr
.ifr_mtu
;
438 if (ife
->type
== ARPHRD_SLIP
|| ife
->type
== ARPHRD_CSLIP
||
439 ife
->type
== ARPHRD_SLIP6
|| ife
->type
== ARPHRD_CSLIP6
||
440 ife
->type
== ARPHRD_ADAPT
) {
442 strcpy(ifr
.ifr_name
, ifname
);
443 if (ioctl(skfd
, SIOCGOUTFILL
, &ifr
) < 0)
446 ife
->outfill
= (unsigned int) ifr
.ifr_data
;
448 #ifdef SIOCGKEEPALIVE
449 strcpy(ifr
.ifr_name
, ifname
);
450 if (ioctl(skfd
, SIOCGKEEPALIVE
, &ifr
) < 0)
453 ife
->keepalive
= (unsigned int) ifr
.ifr_data
;
458 strcpy(ifr
.ifr_name
, ifname
);
459 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0)
460 memset(&ife
->map
, 0, sizeof(struct ifmap
));
462 memcpy(&ife
->map
, &ifr
.ifr_map
, sizeof(struct ifmap
));
464 strcpy(ifr
.ifr_name
, ifname
);
465 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0)
466 memset(&ife
->map
, 0, sizeof(struct ifmap
));
468 ife
->map
= ifr
.ifr_map
;
470 #ifdef HAVE_TXQUEUELEN
471 strcpy(ifr
.ifr_name
, ifname
);
472 if (ioctl(skfd
, SIOCGIFTXQLEN
, &ifr
) < 0)
473 ife
->tx_queue_len
= -1; /* unknown value */
475 ife
->tx_queue_len
= ifr
.ifr_qlen
;
477 ife
->tx_queue_len
= -1; /* unknown value */
482 fd
= get_socket_for_af(AF_INET
);
484 strcpy(ifr
.ifr_name
, ifname
);
485 ifr
.ifr_addr
.sa_family
= AF_INET
;
486 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
488 ife
->addr
= ifr
.ifr_addr
;
489 strcpy(ifr
.ifr_name
, ifname
);
490 if (ioctl(fd
, SIOCGIFDSTADDR
, &ifr
) < 0)
491 memset(&ife
->dstaddr
, 0, sizeof(struct sockaddr
));
493 ife
->dstaddr
= ifr
.ifr_dstaddr
;
495 strcpy(ifr
.ifr_name
, ifname
);
496 if (ioctl(fd
, SIOCGIFBRDADDR
, &ifr
) < 0)
497 memset(&ife
->broadaddr
, 0, sizeof(struct sockaddr
));
499 ife
->broadaddr
= ifr
.ifr_broadaddr
;
501 strcpy(ifr
.ifr_name
, ifname
);
502 if (ioctl(fd
, SIOCGIFNETMASK
, &ifr
) < 0)
503 memset(&ife
->netmask
, 0, sizeof(struct sockaddr
));
505 ife
->netmask
= ifr
.ifr_netmask
;
507 memset(&ife
->addr
, 0, sizeof(struct sockaddr
));
512 /* DDP address maybe ? */
513 fd
= get_socket_for_af(AF_APPLETALK
);
515 strcpy(ifr
.ifr_name
, ifname
);
516 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
517 ife
->ddpaddr
= ifr
.ifr_addr
;
524 /* Look for IPX addresses with all framing types */
525 fd
= get_socket_for_af(AF_IPX
);
527 strcpy(ifr
.ifr_name
, ifname
);
528 if (!ipx_getaddr(fd
, IPX_FRAME_ETHERII
, &ifr
)) {
530 ife
->ipxaddr_bb
= ifr
.ifr_addr
;
532 strcpy(ifr
.ifr_name
, ifname
);
533 if (!ipx_getaddr(fd
, IPX_FRAME_SNAP
, &ifr
)) {
535 ife
->ipxaddr_sn
= ifr
.ifr_addr
;
537 strcpy(ifr
.ifr_name
, ifname
);
538 if (!ipx_getaddr(fd
, IPX_FRAME_8023
, &ifr
)) {
540 ife
->ipxaddr_e3
= ifr
.ifr_addr
;
542 strcpy(ifr
.ifr_name
, ifname
);
543 if (!ipx_getaddr(fd
, IPX_FRAME_8022
, &ifr
)) {
545 ife
->ipxaddr_e2
= ifr
.ifr_addr
;
551 /* Econet address maybe? */
552 fd
= get_socket_for_af(AF_ECONET
);
554 strcpy(ifr
.ifr_name
, ifname
);
555 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
556 ife
->ecaddr
= ifr
.ifr_addr
;
565 int do_if_fetch(struct interface
*ife
)
567 if (if_fetch(ife
) < 0) {
569 if (errno
== ENODEV
) {
570 /* Give better error message for this case. */
571 errmsg
= _("Device not found");
573 errmsg
= strerror(errno
);
575 fprintf(stderr
, _("%s: error fetching interface information: %s\n"),
582 int do_if_print(struct interface
*ife
, void *cookie
)
584 int *opt_a
= (int *) cookie
;
587 res
= do_if_fetch(ife
);
589 if ((ife
->flags
& IFF_UP
) || *opt_a
)
595 void ife_print_short(struct interface
*ptr
)
597 printf("%-5.5s ", ptr
->name
);
598 printf("%5d %-2d ", ptr
->mtu
, ptr
->metric
);
599 /* If needed, display the interface statistics. */
600 if (ptr
->statistics_valid
) {
601 printf("%8llu %6lu %6lu %6lu ",
602 ptr
->stats
.rx_packets
, ptr
->stats
.rx_errors
,
603 ptr
->stats
.rx_dropped
, ptr
->stats
.rx_fifo_errors
);
604 printf("%8llu %6lu %6lu %6lu ",
605 ptr
->stats
.tx_packets
, ptr
->stats
.tx_errors
,
606 ptr
->stats
.tx_dropped
, ptr
->stats
.tx_fifo_errors
);
608 printf("%-56s", _(" - no statistics available -"));
610 /* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
612 printf(_("[NO FLAGS]"));
613 if (ptr
->flags
& IFF_ALLMULTI
)
615 if (ptr
->flags
& IFF_BROADCAST
)
617 if (ptr
->flags
& IFF_DEBUG
)
619 if (ptr
->flags
& IFF_LOOPBACK
)
621 if (ptr
->flags
& IFF_MULTICAST
)
624 if (ptr
->flags
& IFF_DYNAMIC
)
627 if (ptr
->flags
& IFF_PROMISC
)
629 if (ptr
->flags
& IFF_NOTRAILERS
)
631 if (ptr
->flags
& IFF_NOARP
)
633 if (ptr
->flags
& IFF_POINTOPOINT
)
635 if (ptr
->flags
& IFF_SLAVE
)
637 if (ptr
->flags
& IFF_MASTER
)
639 if (ptr
->flags
& IFF_RUNNING
)
641 if (ptr
->flags
& IFF_UP
)
643 /* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
647 void ife_print_long(struct interface
*ptr
)
652 int can_compress
= 0;
653 unsigned long long rx
, tx
, short_rx
, short_tx
;
654 const char *Rext
= "b";
655 const char *Text
= "b";
658 static struct aftype
*ipxtype
= NULL
;
661 static struct aftype
*ectype
= NULL
;
664 static struct aftype
*ddptype
= NULL
;
668 char addr6
[40], devname
[20];
669 struct sockaddr_in6 sap
;
670 int plen
, scope
, dad_status
, if_idx
;
671 extern struct aftype inet6_aftype
;
675 ap
= get_afntype(ptr
->addr
.sa_family
);
681 if (hf
== ARPHRD_CSLIP
|| hf
== ARPHRD_CSLIP6
)
684 hw
= get_hwntype(hf
);
686 hw
= get_hwntype(-1);
688 printf(_("%-9.9s Link encap:%s "), ptr
->name
, hw
->title
);
689 /* For some hardware types (eg Ash, ATM) we don't print the
690 hardware address if it's null. */
691 if (hw
->print
!= NULL
&& (! (hw_null_address(hw
, ptr
->hwaddr
) &&
692 hw
->suppress_null_addr
)))
693 printf(_("HWaddr %s "), hw
->print(ptr
->hwaddr
));
695 if (ptr
->flags
& IFF_PORTSEL
) {
696 printf(_("Media:%s"), if_port_text
[ptr
->map
.port
][0]);
697 if (ptr
->flags
& IFF_AUTOMEDIA
)
705 printf(_(" %s addr:%s "), ap
->name
,
706 ap
->sprint(&ptr
->addr
, 1));
707 if (ptr
->flags
& IFF_POINTOPOINT
) {
708 printf(_(" P-t-P:%s "), ap
->sprint(&ptr
->dstaddr
, 1));
710 if (ptr
->flags
& IFF_BROADCAST
) {
711 printf(_(" Bcast:%s "), ap
->sprint(&ptr
->broadaddr
, 1));
713 printf(_(" Mask:%s\n"), ap
->sprint(&ptr
->netmask
, 1));
718 /* FIXME: should be integrated into interface.c. */
720 if ((f
= fopen(_PATH_PROCNET_IFINET6
, "r")) != NULL
) {
721 while (fscanf(f
, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
722 addr6p
[0], addr6p
[1], addr6p
[2], addr6p
[3],
723 addr6p
[4], addr6p
[5], addr6p
[6], addr6p
[7],
724 &if_idx
, &plen
, &scope
, &dad_status
, devname
) != EOF
) {
725 if (!strcmp(devname
, ptr
->name
)) {
726 sprintf(addr6
, "%s:%s:%s:%s:%s:%s:%s:%s",
727 addr6p
[0], addr6p
[1], addr6p
[2], addr6p
[3],
728 addr6p
[4], addr6p
[5], addr6p
[6], addr6p
[7]);
729 inet6_aftype
.input(1, addr6
, (struct sockaddr
*) &sap
);
730 printf(_(" inet6 addr: %s/%d"),
731 inet6_aftype
.sprint((struct sockaddr
*) &sap
, 1), plen
);
732 printf(_(" Scope:"));
737 case IPV6_ADDR_LINKLOCAL
:
740 case IPV6_ADDR_SITELOCAL
:
743 case IPV6_ADDR_COMPATv4
:
746 case IPV6_ADDR_LOOPBACK
:
750 printf(_("Unknown"));
761 ipxtype
= get_afntype(AF_IPX
);
763 if (ipxtype
!= NULL
) {
765 printf(_(" IPX/Ethernet II addr:%s\n"),
766 ipxtype
->sprint(&ptr
->ipxaddr_bb
, 1));
768 printf(_(" IPX/Ethernet SNAP addr:%s\n"),
769 ipxtype
->sprint(&ptr
->ipxaddr_sn
, 1));
771 printf(_(" IPX/Ethernet 802.2 addr:%s\n"),
772 ipxtype
->sprint(&ptr
->ipxaddr_e2
, 1));
774 printf(_(" IPX/Ethernet 802.3 addr:%s\n"),
775 ipxtype
->sprint(&ptr
->ipxaddr_e3
, 1));
781 ddptype
= get_afntype(AF_APPLETALK
);
782 if (ddptype
!= NULL
) {
784 printf(_(" EtherTalk Phase 2 addr:%s\n"), ddptype
->sprint(&ptr
->ddpaddr
, 1));
790 ectype
= get_afntype(AF_ECONET
);
791 if (ectype
!= NULL
) {
793 printf(_(" econet addr:%s\n"), ectype
->sprint(&ptr
->ecaddr
, 1));
798 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */
800 printf(_("[NO FLAGS] "));
801 if (ptr
->flags
& IFF_UP
)
803 if (ptr
->flags
& IFF_BROADCAST
)
804 printf(_("BROADCAST "));
805 if (ptr
->flags
& IFF_DEBUG
)
807 if (ptr
->flags
& IFF_LOOPBACK
)
808 printf(_("LOOPBACK "));
809 if (ptr
->flags
& IFF_POINTOPOINT
)
810 printf(_("POINTOPOINT "));
811 if (ptr
->flags
& IFF_NOTRAILERS
)
812 printf(_("NOTRAILERS "));
813 if (ptr
->flags
& IFF_RUNNING
)
814 printf(_("RUNNING "));
815 if (ptr
->flags
& IFF_NOARP
)
817 if (ptr
->flags
& IFF_PROMISC
)
818 printf(_("PROMISC "));
819 if (ptr
->flags
& IFF_ALLMULTI
)
820 printf(_("ALLMULTI "));
821 if (ptr
->flags
& IFF_SLAVE
)
823 if (ptr
->flags
& IFF_MASTER
)
824 printf(_("MASTER "));
825 if (ptr
->flags
& IFF_MULTICAST
)
826 printf(_("MULTICAST "));
828 if (ptr
->flags
& IFF_DYNAMIC
)
829 printf(_("DYNAMIC "));
831 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short */
832 printf(_(" MTU:%d Metric:%d"),
833 ptr
->mtu
, ptr
->metric
? ptr
->metric
: 1);
834 #ifdef SIOCSKEEPALIVE
835 if (ptr
->outfill
|| ptr
->keepalive
)
836 printf(_(" Outfill:%d Keepalive:%d"),
837 ptr
->outfill
, ptr
->keepalive
);
841 /* If needed, display the interface statistics. */
843 if (ptr
->statistics_valid
) {
844 /* XXX: statistics are currently only printed for the primary address,
845 * not for the aliases, although strictly speaking they're shared
850 printf(_("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
851 ptr
->stats
.rx_packets
, ptr
->stats
.rx_errors
,
852 ptr
->stats
.rx_dropped
, ptr
->stats
.rx_fifo_errors
,
853 ptr
->stats
.rx_frame_errors
);
855 printf(_(" compressed:%lu\n"), ptr
->stats
.rx_compressed
);
857 rx
= ptr
->stats
.rx_bytes
;
858 tx
= ptr
->stats
.tx_bytes
;
861 if (rx
> 1125899906842624ull) {
862 short_rx
/= 1125899906842624ull;
864 } else if (rx
> 1099511627776ull) {
865 short_rx
/= 1099511627776ull;
867 } else if (rx
> 1073741824ull) {
868 short_rx
/= 1073741824ull;
870 } else if (rx
> 1048576) {
873 } else if (rx
> 1024) {
877 if (tx
> 1125899906842624ull) {
878 short_tx
/= 1125899906842624ull;
880 } else if (tx
> 1099511627776ull) {
881 short_tx
/= 1099511627776ull;
883 } else if (tx
> 1073741824ull) {
884 short_tx
/= 1073741824ull;
886 } else if (tx
> 1048576) {
889 } else if (tx
> 1024) {
895 printf(_("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"),
896 ptr
->stats
.tx_packets
, ptr
->stats
.tx_errors
,
897 ptr
->stats
.tx_dropped
, ptr
->stats
.tx_fifo_errors
,
898 ptr
->stats
.tx_carrier_errors
);
899 printf(_(" collisions:%lu "), ptr
->stats
.collisions
);
901 printf(_("compressed:%lu "), ptr
->stats
.tx_compressed
);
902 if (ptr
->tx_queue_len
!= -1)
903 printf(_("txqueuelen:%d "), ptr
->tx_queue_len
);
905 printf(_("RX bytes:%llu (%lu.%lu %s) TX bytes:%llu (%lu.%lu %s)\n"),
906 rx
, (unsigned long)(short_rx
/ 10),
907 (unsigned long)(short_rx
% 10), Rext
,
908 tx
, (unsigned long)(short_tx
/ 10),
909 (unsigned long)(short_tx
% 10), Text
);
912 if ((ptr
->map
.irq
|| ptr
->map
.mem_start
|| ptr
->map
.dma
||
913 ptr
->map
.base_addr
>= 0x100)) {
916 printf(_("Interrupt:%d "), ptr
->map
.irq
);
917 if (ptr
->map
.base_addr
>= 0x100) /* Only print devices using it for
919 printf(_("Base address:0x%x "), ptr
->map
.base_addr
);
920 if (ptr
->map
.mem_start
) {
921 printf(_("Memory:%lx-%lx "), ptr
->map
.mem_start
, ptr
->map
.mem_end
);
924 printf(_("DMA chan:%x "), ptr
->map
.dma
);
930 void ife_print(struct interface
*i
)