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.24 2002/06/14 01:33: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 static struct interface
*int_list
, *int_last
;
92 static int if_readlist_proc(char *);
94 static struct interface
*if_cache_add(char *name
)
96 struct interface
*ife
, **nextp
, *new;
101 for (ife
= int_last
; ife
; ife
= ife
->prev
) {
102 int n
= nstrcmp(ife
->name
, name
);
109 safe_strncpy(new->name
, name
, IFNAMSIZ
);
110 nextp
= ife
? &ife
->next
: &int_list
;
114 new->next
->prev
= new;
121 struct interface
*lookup_interface(char *name
)
123 struct interface
*ife
= NULL
;
125 if (if_readlist_proc(name
) < 0)
127 ife
= if_cache_add(name
);
131 int for_all_interfaces(int (*doit
) (struct interface
*, void *), void *cookie
)
133 struct interface
*ife
;
135 if (!int_list
&& (if_readlist() < 0))
137 for (ife
= int_list
; ife
; ife
= ife
->next
) {
138 int err
= doit(ife
, cookie
);
145 int if_cache_free(void)
147 struct interface
*ife
;
148 while ((ife
= int_list
) != NULL
) {
149 int_list
= ife
->next
;
156 static int if_readconf(void)
164 /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets
166 skfd
= get_socket_for_af(AF_INET
);
168 fprintf(stderr
, _("warning: no inet socket available: %s\n"),
170 /* Try to soldier on with whatever socket we can get hold of. */
171 skfd
= sockets_open(0);
178 ifc
.ifc_len
= sizeof(struct ifreq
) * numreqs
;
179 ifc
.ifc_buf
= xrealloc(ifc
.ifc_buf
, ifc
.ifc_len
);
181 if (ioctl(skfd
, SIOCGIFCONF
, &ifc
) < 0) {
182 perror("SIOCGIFCONF");
185 if (ifc
.ifc_len
== sizeof(struct ifreq
) * numreqs
) {
186 /* assume it overflowed and try again */
194 for (n
= 0; n
< ifc
.ifc_len
; n
+= sizeof(struct ifreq
)) {
195 if_cache_add(ifr
->ifr_name
);
205 char *get_name(char *name
, char *p
)
212 if (*p
== ':') { /* could be an alias */
214 while (*p
&& isdigit(*p
)) p
++;
216 /* Yes it is, backup and copy it. */
219 while (*p
&& isdigit(*p
)) {
235 int procnetdev_version(char *buf
)
237 if (strstr(buf
, "compressed"))
239 if (strstr(buf
, "bytes"))
244 int get_dev_fields(char *bp
, struct interface
*ife
)
246 switch (procnetdev_vsn
) {
249 "%Lu %Lu %lu %lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu %lu",
250 &ife
->stats
.rx_bytes
,
251 &ife
->stats
.rx_packets
,
252 &ife
->stats
.rx_errors
,
253 &ife
->stats
.rx_dropped
,
254 &ife
->stats
.rx_fifo_errors
,
255 &ife
->stats
.rx_frame_errors
,
256 &ife
->stats
.rx_compressed
,
257 &ife
->stats
.rx_multicast
,
259 &ife
->stats
.tx_bytes
,
260 &ife
->stats
.tx_packets
,
261 &ife
->stats
.tx_errors
,
262 &ife
->stats
.tx_dropped
,
263 &ife
->stats
.tx_fifo_errors
,
264 &ife
->stats
.collisions
,
265 &ife
->stats
.tx_carrier_errors
,
266 &ife
->stats
.tx_compressed
);
269 sscanf(bp
, "%Lu %Lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu",
270 &ife
->stats
.rx_bytes
,
271 &ife
->stats
.rx_packets
,
272 &ife
->stats
.rx_errors
,
273 &ife
->stats
.rx_dropped
,
274 &ife
->stats
.rx_fifo_errors
,
275 &ife
->stats
.rx_frame_errors
,
277 &ife
->stats
.tx_bytes
,
278 &ife
->stats
.tx_packets
,
279 &ife
->stats
.tx_errors
,
280 &ife
->stats
.tx_dropped
,
281 &ife
->stats
.tx_fifo_errors
,
282 &ife
->stats
.collisions
,
283 &ife
->stats
.tx_carrier_errors
);
284 ife
->stats
.rx_multicast
= 0;
287 sscanf(bp
, "%Lu %lu %lu %lu %lu %Lu %lu %lu %lu %lu %lu",
288 &ife
->stats
.rx_packets
,
289 &ife
->stats
.rx_errors
,
290 &ife
->stats
.rx_dropped
,
291 &ife
->stats
.rx_fifo_errors
,
292 &ife
->stats
.rx_frame_errors
,
294 &ife
->stats
.tx_packets
,
295 &ife
->stats
.tx_errors
,
296 &ife
->stats
.tx_dropped
,
297 &ife
->stats
.tx_fifo_errors
,
298 &ife
->stats
.collisions
,
299 &ife
->stats
.tx_carrier_errors
);
300 ife
->stats
.rx_bytes
= 0;
301 ife
->stats
.tx_bytes
= 0;
302 ife
->stats
.rx_multicast
= 0;
308 static int if_readlist_proc(char *target
)
312 struct interface
*ife
;
315 fh
= fopen(_PATH_PROCNET_DEV
, "r");
317 fprintf(stderr
, _("Warning: cannot open %s (%s). Limited output.\n"),
318 _PATH_PROCNET_DEV
, strerror(errno
));
319 return if_readconf();
321 fgets(buf
, sizeof buf
, fh
); /* eat line */
322 fgets(buf
, sizeof buf
, fh
);
324 #if 0 /* pretty, but can't cope with missing fields */
325 fmt
= proc_gen_fmt(_PATH_PROCNET_DEV
, 1, fh
,
326 "face", "", /* parsed separately */
347 procnetdev_vsn
= procnetdev_version(buf
);
351 while (fgets(buf
, sizeof buf
, fh
)) {
352 char *s
, name
[IFNAMSIZ
];
353 s
= get_name(name
, buf
);
354 ife
= if_cache_add(name
);
355 get_dev_fields(s
, ife
);
356 ife
->statistics_valid
= 1;
357 if (target
&& !strcmp(target
,name
))
361 perror(_PATH_PROCNET_DEV
);
372 int if_readlist(void)
374 /* caller will/should check not to call this too often
375 * (i.e. only if int_list!= NULL
377 int err
= if_readlist_proc(NULL
);
383 /* Support for fetching an IPX address */
386 static int ipx_getaddr(int sock
, int ft
, struct ifreq
*ifr
)
388 ((struct sockaddr_ipx
*) &ifr
->ifr_addr
)->sipx_type
= ft
;
389 return ioctl(sock
, SIOCGIFADDR
, ifr
);
393 /* Fetch the interface configuration from the kernel. */
394 int if_fetch(struct interface
*ife
)
398 char *ifname
= ife
->name
;
400 strcpy(ifr
.ifr_name
, ifname
);
401 if (ioctl(skfd
, SIOCGIFFLAGS
, &ifr
) < 0)
403 ife
->flags
= ifr
.ifr_flags
;
405 strcpy(ifr
.ifr_name
, ifname
);
406 if (ioctl(skfd
, SIOCGIFHWADDR
, &ifr
) < 0)
407 memset(ife
->hwaddr
, 0, 32);
409 memcpy(ife
->hwaddr
, ifr
.ifr_hwaddr
.sa_data
, 8);
411 ife
->type
= ifr
.ifr_hwaddr
.sa_family
;
413 strcpy(ifr
.ifr_name
, ifname
);
414 if (ioctl(skfd
, SIOCGIFMETRIC
, &ifr
) < 0)
417 ife
->metric
= ifr
.ifr_metric
;
419 strcpy(ifr
.ifr_name
, ifname
);
420 if (ioctl(skfd
, SIOCGIFMTU
, &ifr
) < 0)
423 ife
->mtu
= ifr
.ifr_mtu
;
426 if (ife
->type
== ARPHRD_SLIP
|| ife
->type
== ARPHRD_CSLIP
||
427 ife
->type
== ARPHRD_SLIP6
|| ife
->type
== ARPHRD_CSLIP6
||
428 ife
->type
== ARPHRD_ADAPT
) {
430 strcpy(ifr
.ifr_name
, ifname
);
431 if (ioctl(skfd
, SIOCGOUTFILL
, &ifr
) < 0)
434 ife
->outfill
= (unsigned int) ifr
.ifr_data
;
436 #ifdef SIOCGKEEPALIVE
437 strcpy(ifr
.ifr_name
, ifname
);
438 if (ioctl(skfd
, SIOCGKEEPALIVE
, &ifr
) < 0)
441 ife
->keepalive
= (unsigned int) ifr
.ifr_data
;
446 strcpy(ifr
.ifr_name
, ifname
);
447 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0)
448 memset(&ife
->map
, 0, sizeof(struct ifmap
));
450 memcpy(&ife
->map
, &ifr
.ifr_map
, sizeof(struct ifmap
));
452 strcpy(ifr
.ifr_name
, ifname
);
453 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0)
454 memset(&ife
->map
, 0, sizeof(struct ifmap
));
456 ife
->map
= ifr
.ifr_map
;
458 #ifdef HAVE_TXQUEUELEN
459 strcpy(ifr
.ifr_name
, ifname
);
460 if (ioctl(skfd
, SIOCGIFTXQLEN
, &ifr
) < 0)
461 ife
->tx_queue_len
= -1; /* unknown value */
463 ife
->tx_queue_len
= ifr
.ifr_qlen
;
465 ife
->tx_queue_len
= -1; /* unknown value */
470 fd
= get_socket_for_af(AF_INET
);
472 strcpy(ifr
.ifr_name
, ifname
);
473 ifr
.ifr_addr
.sa_family
= AF_INET
;
474 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
476 ife
->addr
= ifr
.ifr_addr
;
477 strcpy(ifr
.ifr_name
, ifname
);
478 if (ioctl(fd
, SIOCGIFDSTADDR
, &ifr
) < 0)
479 memset(&ife
->dstaddr
, 0, sizeof(struct sockaddr
));
481 ife
->dstaddr
= ifr
.ifr_dstaddr
;
483 strcpy(ifr
.ifr_name
, ifname
);
484 if (ioctl(fd
, SIOCGIFBRDADDR
, &ifr
) < 0)
485 memset(&ife
->broadaddr
, 0, sizeof(struct sockaddr
));
487 ife
->broadaddr
= ifr
.ifr_broadaddr
;
489 strcpy(ifr
.ifr_name
, ifname
);
490 if (ioctl(fd
, SIOCGIFNETMASK
, &ifr
) < 0)
491 memset(&ife
->netmask
, 0, sizeof(struct sockaddr
));
493 ife
->netmask
= ifr
.ifr_netmask
;
495 memset(&ife
->addr
, 0, sizeof(struct sockaddr
));
500 /* DDP address maybe ? */
501 fd
= get_socket_for_af(AF_APPLETALK
);
503 strcpy(ifr
.ifr_name
, ifname
);
504 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
505 ife
->ddpaddr
= ifr
.ifr_addr
;
512 /* Look for IPX addresses with all framing types */
513 fd
= get_socket_for_af(AF_IPX
);
515 strcpy(ifr
.ifr_name
, ifname
);
516 if (!ipx_getaddr(fd
, IPX_FRAME_ETHERII
, &ifr
)) {
518 ife
->ipxaddr_bb
= ifr
.ifr_addr
;
520 strcpy(ifr
.ifr_name
, ifname
);
521 if (!ipx_getaddr(fd
, IPX_FRAME_SNAP
, &ifr
)) {
523 ife
->ipxaddr_sn
= ifr
.ifr_addr
;
525 strcpy(ifr
.ifr_name
, ifname
);
526 if (!ipx_getaddr(fd
, IPX_FRAME_8023
, &ifr
)) {
528 ife
->ipxaddr_e3
= ifr
.ifr_addr
;
530 strcpy(ifr
.ifr_name
, ifname
);
531 if (!ipx_getaddr(fd
, IPX_FRAME_8022
, &ifr
)) {
533 ife
->ipxaddr_e2
= ifr
.ifr_addr
;
539 /* Econet address maybe? */
540 fd
= get_socket_for_af(AF_ECONET
);
542 strcpy(ifr
.ifr_name
, ifname
);
543 if (ioctl(fd
, SIOCGIFADDR
, &ifr
) == 0) {
544 ife
->ecaddr
= ifr
.ifr_addr
;
553 int do_if_fetch(struct interface
*ife
)
555 if (if_fetch(ife
) < 0) {
557 if (errno
== ENODEV
) {
558 /* Give better error message for this case. */
559 errmsg
= _("Device not found");
561 errmsg
= strerror(errno
);
563 fprintf(stderr
, _("%s: error fetching interface information: %s\n"),
570 int do_if_print(struct interface
*ife
, void *cookie
)
572 int *opt_a
= (int *) cookie
;
575 res
= do_if_fetch(ife
);
577 if ((ife
->flags
& IFF_UP
) || *opt_a
)
583 void ife_print_short(struct interface
*ptr
)
585 printf("%-5.5s ", ptr
->name
);
586 printf("%5d %-2d", ptr
->mtu
, ptr
->metric
);
587 /* If needed, display the interface statistics. */
588 if (ptr
->statistics_valid
) {
589 printf("%9llu %6lu %6lu %-5lu",
590 ptr
->stats
.rx_packets
, ptr
->stats
.rx_errors
,
591 ptr
->stats
.rx_dropped
, ptr
->stats
.rx_fifo_errors
);
592 printf("%9llu %6lu %6lu %6lu ",
593 ptr
->stats
.tx_packets
, ptr
->stats
.tx_errors
,
594 ptr
->stats
.tx_dropped
, ptr
->stats
.tx_fifo_errors
);
596 printf("%-56s", _(" - no statistics available -"));
598 /* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
600 printf(_("[NO FLAGS]"));
601 if (ptr
->flags
& IFF_ALLMULTI
)
603 if (ptr
->flags
& IFF_BROADCAST
)
605 if (ptr
->flags
& IFF_DEBUG
)
607 if (ptr
->flags
& IFF_LOOPBACK
)
609 if (ptr
->flags
& IFF_MULTICAST
)
612 if (ptr
->flags
& IFF_DYNAMIC
)
615 if (ptr
->flags
& IFF_PROMISC
)
617 if (ptr
->flags
& IFF_NOTRAILERS
)
619 if (ptr
->flags
& IFF_NOARP
)
621 if (ptr
->flags
& IFF_POINTOPOINT
)
623 if (ptr
->flags
& IFF_SLAVE
)
625 if (ptr
->flags
& IFF_MASTER
)
627 if (ptr
->flags
& IFF_RUNNING
)
629 if (ptr
->flags
& IFF_UP
)
631 /* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
635 void ife_print_long(struct interface
*ptr
)
640 int can_compress
= 0;
641 unsigned long long rx
, tx
, short_rx
, short_tx
;
642 const char *Rext
= "b";
643 const char *Text
= "b";
646 static struct aftype
*ipxtype
= NULL
;
649 static struct aftype
*ectype
= NULL
;
652 static struct aftype
*ddptype
= NULL
;
656 char addr6
[40], devname
[20];
657 struct sockaddr_in6 sap
;
658 int plen
, scope
, dad_status
, if_idx
;
659 extern struct aftype inet6_aftype
;
663 ap
= get_afntype(ptr
->addr
.sa_family
);
669 if (hf
== ARPHRD_CSLIP
|| hf
== ARPHRD_CSLIP6
)
672 hw
= get_hwntype(hf
);
674 hw
= get_hwntype(-1);
676 printf(_("%-9.9s Link encap:%s "), ptr
->name
, hw
->title
);
677 /* For some hardware types (eg Ash, ATM) we don't print the
678 hardware address if it's null. */
679 if (hw
->print
!= NULL
&& (! (hw_null_address(hw
, ptr
->hwaddr
) &&
680 hw
->suppress_null_addr
)))
681 printf(_("HWaddr %s "), hw
->print(ptr
->hwaddr
));
683 if (ptr
->flags
& IFF_PORTSEL
) {
684 printf(_("Media:%s"), if_port_text
[ptr
->map
.port
][0]);
685 if (ptr
->flags
& IFF_AUTOMEDIA
)
693 printf(_(" %s addr:%s "), ap
->name
,
694 ap
->sprint(&ptr
->addr
, 1));
695 if (ptr
->flags
& IFF_POINTOPOINT
) {
696 printf(_(" P-t-P:%s "), ap
->sprint(&ptr
->dstaddr
, 1));
698 if (ptr
->flags
& IFF_BROADCAST
) {
699 printf(_(" Bcast:%s "), ap
->sprint(&ptr
->broadaddr
, 1));
701 printf(_(" Mask:%s\n"), ap
->sprint(&ptr
->netmask
, 1));
706 /* FIXME: should be integrated into interface.c. */
708 if ((f
= fopen(_PATH_PROCNET_IFINET6
, "r")) != NULL
) {
709 while (fscanf(f
, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
710 addr6p
[0], addr6p
[1], addr6p
[2], addr6p
[3],
711 addr6p
[4], addr6p
[5], addr6p
[6], addr6p
[7],
712 &if_idx
, &plen
, &scope
, &dad_status
, devname
) != EOF
) {
713 if (!strcmp(devname
, ptr
->name
)) {
714 sprintf(addr6
, "%s:%s:%s:%s:%s:%s:%s:%s",
715 addr6p
[0], addr6p
[1], addr6p
[2], addr6p
[3],
716 addr6p
[4], addr6p
[5], addr6p
[6], addr6p
[7]);
717 inet6_aftype
.input(1, addr6
, (struct sockaddr
*) &sap
);
718 printf(_(" inet6 addr: %s/%d"),
719 inet6_aftype
.sprint((struct sockaddr
*) &sap
, 1), plen
);
720 printf(_(" Scope:"));
725 case IPV6_ADDR_LINKLOCAL
:
728 case IPV6_ADDR_SITELOCAL
:
731 case IPV6_ADDR_COMPATv4
:
734 case IPV6_ADDR_LOOPBACK
:
738 printf(_("Unknown"));
749 ipxtype
= get_afntype(AF_IPX
);
751 if (ipxtype
!= NULL
) {
753 printf(_(" IPX/Ethernet II addr:%s\n"),
754 ipxtype
->sprint(&ptr
->ipxaddr_bb
, 1));
756 printf(_(" IPX/Ethernet SNAP addr:%s\n"),
757 ipxtype
->sprint(&ptr
->ipxaddr_sn
, 1));
759 printf(_(" IPX/Ethernet 802.2 addr:%s\n"),
760 ipxtype
->sprint(&ptr
->ipxaddr_e2
, 1));
762 printf(_(" IPX/Ethernet 802.3 addr:%s\n"),
763 ipxtype
->sprint(&ptr
->ipxaddr_e3
, 1));
769 ddptype
= get_afntype(AF_APPLETALK
);
770 if (ddptype
!= NULL
) {
772 printf(_(" EtherTalk Phase 2 addr:%s\n"), ddptype
->sprint(&ptr
->ddpaddr
, 1));
778 ectype
= get_afntype(AF_ECONET
);
779 if (ectype
!= NULL
) {
781 printf(_(" econet addr:%s\n"), ectype
->sprint(&ptr
->ecaddr
, 1));
786 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */
788 printf(_("[NO FLAGS] "));
789 if (ptr
->flags
& IFF_UP
)
791 if (ptr
->flags
& IFF_BROADCAST
)
792 printf(_("BROADCAST "));
793 if (ptr
->flags
& IFF_DEBUG
)
795 if (ptr
->flags
& IFF_LOOPBACK
)
796 printf(_("LOOPBACK "));
797 if (ptr
->flags
& IFF_POINTOPOINT
)
798 printf(_("POINTOPOINT "));
799 if (ptr
->flags
& IFF_NOTRAILERS
)
800 printf(_("NOTRAILERS "));
801 if (ptr
->flags
& IFF_RUNNING
)
802 printf(_("RUNNING "));
803 if (ptr
->flags
& IFF_NOARP
)
805 if (ptr
->flags
& IFF_PROMISC
)
806 printf(_("PROMISC "));
807 if (ptr
->flags
& IFF_ALLMULTI
)
808 printf(_("ALLMULTI "));
809 if (ptr
->flags
& IFF_SLAVE
)
811 if (ptr
->flags
& IFF_MASTER
)
812 printf(_("MASTER "));
813 if (ptr
->flags
& IFF_MULTICAST
)
814 printf(_("MULTICAST "));
816 if (ptr
->flags
& IFF_DYNAMIC
)
817 printf(_("DYNAMIC "));
819 /* DONT FORGET TO ADD THE FLAGS IN ife_print_short */
820 printf(_(" MTU:%d Metric:%d"),
821 ptr
->mtu
, ptr
->metric
? ptr
->metric
: 1);
822 #ifdef SIOCSKEEPALIVE
823 if (ptr
->outfill
|| ptr
->keepalive
)
824 printf(_(" Outfill:%d Keepalive:%d"),
825 ptr
->outfill
, ptr
->keepalive
);
829 /* If needed, display the interface statistics. */
831 if (ptr
->statistics_valid
) {
832 /* XXX: statistics are currently only printed for the primary address,
833 * not for the aliases, although strictly speaking they're shared
838 printf(_("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
839 ptr
->stats
.rx_packets
, ptr
->stats
.rx_errors
,
840 ptr
->stats
.rx_dropped
, ptr
->stats
.rx_fifo_errors
,
841 ptr
->stats
.rx_frame_errors
);
843 printf(_(" compressed:%lu\n"), ptr
->stats
.rx_compressed
);
845 rx
= ptr
->stats
.rx_bytes
;
846 tx
= ptr
->stats
.tx_bytes
;
849 if (rx
> 1125899906842624) {
850 short_rx
/= 1125899906842624;
852 } else if (rx
> 1099511627776) {
853 short_rx
/= 1099511627776;
855 } else if (rx
> 1073741824) {
856 short_rx
/= 1073741824;
858 } else if (rx
> 1048576) {
861 } else if (rx
> 1024) {
865 if (tx
> 1125899906842624) {
866 short_tx
/= 1125899906842624;
868 } else if (tx
> 1099511627776) {
869 short_tx
/= 1099511627776;
871 } else if (tx
> 1073741824) {
872 short_tx
/= 1073741824;
874 } else if (tx
> 1048576) {
877 } else if (tx
> 1024) {
883 printf(_("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"),
884 ptr
->stats
.tx_packets
, ptr
->stats
.tx_errors
,
885 ptr
->stats
.tx_dropped
, ptr
->stats
.tx_fifo_errors
,
886 ptr
->stats
.tx_carrier_errors
);
887 printf(_(" collisions:%lu "), ptr
->stats
.collisions
);
889 printf(_("compressed:%lu "), ptr
->stats
.tx_compressed
);
890 if (ptr
->tx_queue_len
!= -1)
891 printf(_("txqueuelen:%d "), ptr
->tx_queue_len
);
893 printf(_("RX bytes:%llu (%lu.%lu %s) TX bytes:%llu (%lu.%lu %s)\n"),
894 rx
, (unsigned long)(short_rx
/ 10),
895 (unsigned long)(short_rx
% 10), Rext
,
896 tx
, (unsigned long)(short_tx
/ 10),
897 (unsigned long)(short_tx
% 10), Text
);
900 if ((ptr
->map
.irq
|| ptr
->map
.mem_start
|| ptr
->map
.dma
||
901 ptr
->map
.base_addr
>= 0x100)) {
904 printf(_("Interrupt:%d "), ptr
->map
.irq
);
905 if (ptr
->map
.base_addr
>= 0x100) /* Only print devices using it for
907 printf(_("Base address:0x%x "), ptr
->map
.base_addr
);
908 if (ptr
->map
.mem_start
) {
909 printf(_("Memory:%lx-%lx "), ptr
->map
.mem_start
, ptr
->map
.mem_end
);
912 printf(_("DMA chan:%x "), ptr
->map
.dma
);
918 void ife_print(struct interface
*i
)