ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/network_stats.c
(Generate patch)

Comparing projects/libstatgrab/src/libstatgrab/network_stats.c (file contents):
Revision 1.62 by ats, Mon Apr 5 15:40:15 2004 UTC vs.
Revision 1.78 by tdb, Mon Oct 9 14:09:38 2006 UTC

# Line 1 | Line 1
1   /*
2 < * i-scream central monitoring system
2 > * i-scream libstatgrab
3   * http://www.i-scream.org
4   * Copyright (C) 2000-2004 i-scream
5   *
# Line 45 | Line 45
45   #ifdef LINUX
46   #include <stdio.h>
47   #include <sys/types.h>
48 #include <regex.h>
48   #include <sys/ioctl.h>
49   #include <sys/socket.h>
50   #include <net/if.h>
51   #include <ctype.h>
52 < /* Stuff which could be defined by defining KERNEL, but
53 < * that would be a bad idea, so we'll just declare it here
54 < */
52 > #include <linux/version.h>
53 > #include <asm/types.h>
54 > /* These aren't defined by asm/types.h unless the kernel is being
55 >   compiled, but some versions of ethtool.h need them. */
56   typedef __uint8_t u8;
57   typedef __uint16_t u16;
58   typedef __uint32_t u32;
# Line 70 | Line 70 | typedef __uint64_t u64;
70   #include <sys/ioctl.h>
71   #include <unistd.h>
72   #endif
73 + #ifdef WIN32
74 + #include <windows.h>
75 + #include <Iphlpapi.h>
76 + #include "win32.h"
77 + #endif
78  
79   static void network_stat_init(sg_network_io_stats *s) {
80          s->interface_name = NULL;
# Line 87 | Line 92 | static void network_stat_destroy(sg_network_io_stats *
92   }
93  
94   VECTOR_DECLARE_STATIC(network_stats, sg_network_io_stats, 5,
95 <                      network_stat_init, network_stat_destroy);
95 >                      network_stat_init, network_stat_destroy);
96  
97 + #ifdef WIN32
98 + static PMIB_IFTABLE win32_get_devices()
99 + {
100 +        PMIB_IFTABLE if_table;
101 +        PMIB_IFTABLE tmp;
102 +        unsigned long dwSize = 0;
103 +
104 +        // Allocate memory for pointers
105 +        if_table = sg_malloc(sizeof(MIB_IFTABLE));
106 +        if(if_table == NULL) {
107 +                return NULL;
108 +        }
109 +
110 +        // Get necessary size for the buffer
111 +        if(GetIfTable(if_table, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
112 +                tmp = sg_realloc(if_table, dwSize);
113 +                if(tmp == NULL) {
114 +                        free(if_table);
115 +                        return NULL;
116 +                }
117 +                if_table = tmp;
118 +        }
119 +
120 +        // Get the data
121 +        if(GetIfTable(if_table, &dwSize, 0) != NO_ERROR) {
122 +                free(if_table);
123 +                return NULL;
124 +        }
125 +        return if_table;
126 + }
127 + #endif /* WIN32 */
128 +
129   sg_network_io_stats *sg_get_network_io_stats(int *entries){
130          int interfaces;
131          sg_network_io_stats *network_stat_ptr;
132  
133   #ifdef SOLARIS
134 <        kstat_ctl_t *kc;
135 <        kstat_t *ksp;
134 >        kstat_ctl_t *kc;
135 >        kstat_t *ksp;
136          kstat_named_t *knp;
137   #endif
138  
# Line 110 | Line 147 | sg_network_io_stats *sg_get_network_io_stats(int *entr
147          struct ifaddrs *net, *net_ptr;
148          struct if_data *net_data;
149   #endif
150 + #ifdef WIN32
151 +        PMIB_IFTABLE if_table;
152 +        MIB_IFROW if_row;
153 +        int i, no, j;
154  
155 +        /* used for duplicate interface names. 5 for space, hash, up to two
156 +         * numbers and terminating slash */
157 +        char buf[5];
158 + #endif
159 +
160   #ifdef ALLBSD
161          if(getifaddrs(&net) != 0){
162 +                sg_set_error_with_errno(SG_ERROR_GETIFADDRS, NULL);
163                  return NULL;
164          }
165  
# Line 127 | Line 174 | sg_network_io_stats *sg_get_network_io_stats(int *entr
174                  network_stat_ptr=network_stats+interfaces;
175                  
176                  if (sg_update_string(&network_stat_ptr->interface_name,
177 <                                     net_ptr->ifa_name) == NULL) {
177 >                                     net_ptr->ifa_name) < 0) {
178                          return NULL;
179                  }
180                  net_data=(struct if_data *)net_ptr->ifa_data;
# Line 145 | Line 192 | sg_network_io_stats *sg_get_network_io_stats(int *entr
192   #endif
193  
194   #ifdef SOLARIS
195 <        if ((kc = kstat_open()) == NULL) {
196 <                return NULL;
197 <        }
195 >        if ((kc = kstat_open()) == NULL) {
196 >                sg_set_error(SG_ERROR_KSTAT_OPEN, NULL);
197 >                return NULL;
198 >        }
199  
200          interfaces=0;
201  
202 <        for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
203 <                if (!strcmp(ksp->ks_class, "net")) {
204 <                        kstat_read(kc, ksp, NULL);
202 >        for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
203 >                if (strcmp(ksp->ks_class, "net") == 0) {
204 >                        kstat_read(kc, ksp, NULL);
205  
206   #ifdef SOL7
207   #define LRX "rbytes"
# Line 182 | Line 230 | sg_network_io_stats *sg_get_network_io_stats(int *entr
230  
231                          /* Create new network_stats */
232                          if (VECTOR_RESIZE(network_stats, interfaces + 1) < 0) {
233 +                                kstat_close(kc);
234                                  return NULL;
235                          }
236                          network_stat_ptr=network_stats+interfaces;
# Line 227 | Line 276 | sg_network_io_stats *sg_get_network_io_stats(int *entr
276  
277                          /* Read interface name */
278                          if (sg_update_string(&network_stat_ptr->interface_name,
279 <                                             ksp->ks_name) == NULL) {
279 >                                             ksp->ks_name) < 0) {
280 >                                kstat_close(kc);
281                                  return NULL;
282                          }
283  
# Line 243 | Line 293 | sg_network_io_stats *sg_get_network_io_stats(int *entr
293   #ifdef LINUX
294          f=fopen("/proc/net/dev", "r");
295          if(f==NULL){
296 +                sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/net/dev");
297                  return NULL;
298          }
299          /* read the 2 lines.. Its the title, so we dont care :) */
# Line 251 | Line 302 | sg_network_io_stats *sg_get_network_io_stats(int *entr
302  
303  
304          if((regcomp(&regex, "^ *([^:]+): *([0-9]+) +([0-9]+) +([0-9]+) +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +([0-9]+) +([0-9]+) +([0-9]+) +[0-9]+ +[0-9]+ +([0-9]+)", REG_EXTENDED))!=0){
305 +                sg_set_error(SG_ERROR_PARSE, NULL);
306                  return NULL;
307          }
308  
# Line 264 | Line 316 | sg_network_io_stats *sg_get_network_io_stats(int *entr
316                  if (VECTOR_RESIZE(network_stats, interfaces + 1) < 0) {
317                          return NULL;
318                  }
319 <                network_stat_ptr=network_stats+interfaces;
319 >                network_stat_ptr=network_stats+interfaces;
320  
321                  if(network_stat_ptr->interface_name!=NULL){
322                          free(network_stat_ptr->interface_name);
# Line 288 | Line 340 | sg_network_io_stats *sg_get_network_io_stats(int *entr
340   #endif
341  
342   #ifdef CYGWIN
343 +        sg_set_error(SG_ERROR_UNSUPPORTED, "Cygwin");
344          return NULL;
345   #endif
346 + #ifdef HPUX
347 +        sg_set_error(SG_ERROR_UNSUPPORTED, "HP-UX");
348 +        return NULL;
349 + #endif
350  
351 + #ifdef WIN32
352 +        interfaces = 0;
353 +
354 +        if((if_table = win32_get_devices()) == NULL) {
355 +                sg_set_error(SG_ERROR_DEVICES, "network");
356 +                return NULL;
357 +        }
358 +
359 +        if(VECTOR_RESIZE(network_stats, if_table->dwNumEntries) < 0) {
360 +                free(if_table);
361 +                return NULL;
362 +        }
363 +
364 +        for (i=0; i<if_table->dwNumEntries; i++) {
365 +                network_stat_ptr=network_stats+i;
366 +                if_row = if_table->table[i];
367 +
368 +                if(sg_update_string(&network_stat_ptr->interface_name,
369 +                                        if_row.bDescr) < 0) {
370 +                        free(if_table);
371 +                        return NULL;
372 +                }
373 +                network_stat_ptr->tx = if_row.dwOutOctets;
374 +                network_stat_ptr->rx = if_row.dwInOctets;
375 +                network_stat_ptr->ipackets = if_row.dwInUcastPkts + if_row.dwInNUcastPkts;
376 +                network_stat_ptr->opackets = if_row.dwOutUcastPkts + if_row.dwOutNUcastPkts;
377 +                network_stat_ptr->ierrors = if_row.dwInErrors;
378 +                network_stat_ptr->oerrors = if_row.dwOutErrors;
379 +                network_stat_ptr->collisions = 0; /* can't do that */
380 +                network_stat_ptr->systime = time(NULL);
381 +
382 +                interfaces++;
383 +        }
384 +        free(if_table);
385 +
386 +        /* Please say there's a nicer way to do this...  If windows has two (or
387 +         * more) identical network cards, GetIfTable returns them with the same
388 +         * name, not like in Device Manager where the other has a #2 etc after
389 +         * it. So, add the #number here. Should we be doing this? Or should the
390 +         * end programs be dealing with duplicate names? Currently breaks
391 +         * watch.pl in rrdgraphing. But Unix does not have the issue of
392 +         * duplicate net device names.
393 +         */
394 +        for (i=0; i<interfaces; i++) {
395 +                no = 2;
396 +                for(j=i+1; j<interfaces; j++) {
397 +                        network_stat_ptr=network_stats+j;
398 +                        if(strcmp(network_stats[i].interface_name,
399 +                                        network_stat_ptr->interface_name) == 0) {
400 +                                if(snprintf(buf, sizeof(buf), " #%d", no) < 0) {
401 +                                        break;
402 +                                }
403 +                                if(sg_concat_string(&network_stat_ptr->interface_name, buf) != 0) {
404 +                                        return NULL;
405 +                                }
406 +
407 +                                no++;
408 +                        }
409 +                }
410 +        }
411 + #endif
412 +
413          *entries=interfaces;
414  
415          return network_stats;  
416   }
417  
418   static long long transfer_diff(long long new, long long old){
419 < #if defined(SOL7) || defined(LINUX) || defined(FREEBSD) || defined(DFBSD) || defined(OPENBSD)
419 > #if defined(SOL7) || defined(LINUX) || defined(FREEBSD) || defined(DFBSD) || defined(OPENBSD) || defined(WIN32)
420          /* 32-bit quantities, so we must explicitly deal with wraparound. */
421   #define MAXVAL 0x100000000LL
422          if (new >= old) {
# Line 313 | Line 432 | static long long transfer_diff(long long new, long lon
432  
433   sg_network_io_stats *sg_get_network_io_stats_diff(int *entries) {
434          VECTOR_DECLARE_STATIC(diff, sg_network_io_stats, 1,
435 <                              network_stat_init, network_stat_destroy);
435 >                              network_stat_init, network_stat_destroy);
436          sg_network_io_stats *src = NULL, *dest;
437          int i, j, diff_count, new_count;
438  
# Line 334 | Line 453 | sg_network_io_stats *sg_get_network_io_stats_diff(int
453                  dest = &diff[i];
454  
455                  if (sg_update_string(&dest->interface_name,
456 <                                     src->interface_name) == NULL) {
456 >                                     src->interface_name) < 0) {
457                          return NULL;
458                  }
459                  dest->rx = src->rx;
# Line 386 | Line 505 | sg_network_io_stats *sg_get_network_io_stats_diff(int
505          return diff;
506   }
507  
508 + int sg_network_io_compare_name(const void *va, const void *vb) {
509 +        const sg_network_io_stats *a = (const sg_network_io_stats *)va;
510 +        const sg_network_io_stats *b = (const sg_network_io_stats *)vb;
511 +
512 +        return strcmp(a->interface_name, b->interface_name);
513 + }
514 +
515   /* NETWORK INTERFACE STATS */
516  
517   static void network_iface_stat_init(sg_network_iface_stats *s) {
518          s->interface_name = NULL;
519          s->speed = 0;
520 <        s->dup = SG_IFACE_DUPLEX_UNKNOWN;
520 >        s->duplex = SG_IFACE_DUPLEX_UNKNOWN;
521   }
522  
523   static void network_iface_stat_destroy(sg_network_iface_stats *s) {
# Line 400 | Line 526 | static void network_iface_stat_destroy(sg_network_ifac
526  
527   sg_network_iface_stats *sg_get_network_iface_stats(int *entries){
528          VECTOR_DECLARE_STATIC(network_iface_stats, sg_network_iface_stats, 5,
529 <                              network_iface_stat_init, network_iface_stat_destroy);
529 >                              network_iface_stat_init, network_iface_stat_destroy);
530          sg_network_iface_stats *network_iface_stat_ptr;
531          int ifaces = 0;
532  
533   #ifdef SOLARIS
534 <        kstat_ctl_t *kc;
535 <        kstat_t *ksp;
534 >        kstat_ctl_t *kc;
535 >        kstat_t *ksp;
536          kstat_named_t *knp;
537          int sock;
538   #endif
539   #ifdef ALLBSD
540 <        struct ifaddrs *net, *net_ptr;
540 >        struct ifaddrs *net, *net_ptr;
541          struct ifmediareq ifmed;
542          struct ifreq ifr;
543          int sock;
544          int x;
545   #endif
546   #ifdef LINUX
547 <        FILE *f;
548 <        /* Horrible big enough, but it should be easily big enough */
549 <        char line[8096];
547 >        FILE *f;
548 >        /* Horrible big enough, but it should be easily big enough */
549 >        char line[8096];
550          int sock;
551   #endif
552 + #ifdef WIN32
553 +        PMIB_IFTABLE if_table;
554 +        MIB_IFROW if_row;
555 +        int i,j,no;
556 +        char buf[5];
557 + #endif
558  
559   #ifdef ALLBSD
560 <        if(getifaddrs(&net) != 0){
561 <                return NULL;
562 <        }
560 >        if(getifaddrs(&net) != 0){
561 >                sg_set_error_with_errno(SG_ERROR_GETIFADDRS, NULL);
562 >                return NULL;
563 >        }
564  
565          if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == 0) return NULL;
566  
567          for(net_ptr=net; net_ptr!=NULL; net_ptr=net_ptr->ifa_next){
568 <                if(net_ptr->ifa_addr->sa_family != AF_LINK) continue;
568 >                if(net_ptr->ifa_addr->sa_family != AF_LINK) continue;
569  
570                  if (VECTOR_RESIZE(network_iface_stats, ifaces + 1) < 0) {
571 <                        return NULL;
572 <                }
573 <                network_iface_stat_ptr = network_iface_stats + ifaces;
571 >                        return NULL;
572 >                }
573 >                network_iface_stat_ptr = network_iface_stats + ifaces;
574  
575                  memset(&ifr, 0, sizeof(ifr));
576                  strncpy(ifr.ifr_name, net_ptr->ifa_name, sizeof(ifr.ifr_name));
# Line 452 | Line 585 | sg_network_iface_stats *sg_get_network_iface_stats(int
585                  }
586  
587                  if (sg_update_string(&network_iface_stat_ptr->interface_name,
588 <                                     net_ptr->ifa_name) == NULL) {
588 >                                     net_ptr->ifa_name) < 0) {
589                          return NULL;
590                  }
591  
592                  network_iface_stat_ptr->speed = 0;
593 <                network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_UNKNOWN;
593 >                network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_UNKNOWN;
594                  ifaces++;
595  
596                  memset(&ifmed, 0, sizeof(struct ifmediareq));
# Line 514 | Line 647 | sg_network_iface_stats *sg_get_network_iface_stats(int
647                  }
648  
649                  if( (ifmed.ifm_active | IFM_FDX) == ifmed.ifm_active ){
650 <                        network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_FULL;
650 >                        network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_FULL;
651                  }else if( (ifmed.ifm_active | IFM_HDX) == ifmed.ifm_active ){
652 <                        network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_HALF;
652 >                        network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_HALF;
653                  }else{
654 <                        network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_UNKNOWN;
654 >                        network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_UNKNOWN;
655                  }
656  
657          }      
# Line 528 | Line 661 | sg_network_iface_stats *sg_get_network_iface_stats(int
661  
662   #ifdef SOLARIS
663          if ((kc = kstat_open()) == NULL) {
664 +                sg_set_error(SG_ERROR_KSTAT_OPEN, NULL);
665                  return NULL;
666          }
667  
668          if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) {
669 +                sg_set_error_with_errno(SG_ERROR_SOCKET, NULL);
670 +                kstat_close(kc);
671                  return NULL;
672          }
673  
674          for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
675 <                if (!strcmp(ksp->ks_class, "net")) {
675 >                if (strcmp(ksp->ks_class, "net") == 0) {
676                          struct ifreq ifr;
677  
678                          kstat_read(kc, ksp, NULL);
# Line 548 | Line 684 | sg_network_iface_stats *sg_get_network_iface_stats(int
684                          }
685  
686                          if (VECTOR_RESIZE(network_iface_stats, ifaces + 1) < 0) {
687 +                                kstat_close(kc);
688                                  return NULL;
689                          }
690                          network_iface_stat_ptr = network_iface_stats + ifaces;
691                          ifaces++;
692  
693                          if (sg_update_string(&network_iface_stat_ptr->interface_name,
694 <                                             ksp->ks_name) == NULL) {
694 >                                             ksp->ks_name) < 0) {
695 >                                kstat_close(kc);
696                                  return NULL;
697                          }
698  
699                          if ((ifr.ifr_flags & IFF_UP) != 0) {
700                                  network_iface_stat_ptr->up = 1;
701                          } else {
702 <                                network_iface_stat_ptr->up = 1;
702 >                                network_iface_stat_ptr->up = 0;
703                          }
704  
705                          if ((knp = kstat_data_lookup(ksp, "ifspeed")) != NULL) {
# Line 570 | Line 708 | sg_network_iface_stats *sg_get_network_iface_stats(int
708                                  network_iface_stat_ptr->speed = 0;
709                          }
710  
711 <                        network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_UNKNOWN;
711 >                        network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_UNKNOWN;
712                          if ((knp = kstat_data_lookup(ksp, "link_duplex")) != NULL) {
713                                  switch (knp->value.ui32) {
714                                  case 1:
715 <                                        network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_HALF;
715 >                                        network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_HALF;
716                                          break;
717                                  case 2:
718 <                                        network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_FULL;
718 >                                        network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_FULL;
719                                          break;
720                                  }
721                          }
# Line 586 | Line 724 | sg_network_iface_stats *sg_get_network_iface_stats(int
724  
725          close(sock);
726          kstat_close(kc);
727 < #endif  
727 > #endif
728   #ifdef LINUX
729          f = fopen("/proc/net/dev", "r");
730 <        if(f == NULL){
731 <                return NULL;
732 <        }
730 >        if(f == NULL){
731 >                sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/net/dev");
732 >                return NULL;
733 >        }
734  
735          /* Setup stuff so we can do the ioctl to get the info */
736          if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
737 +                sg_set_error_with_errno(SG_ERROR_SOCKET, NULL);
738                  return NULL;
739          }
740  
741          /* Ignore first 2 lines.. Just headings */
742 <        if((fgets(line, sizeof(line), f)) == NULL) return NULL;
743 <        if((fgets(line, sizeof(line), f)) == NULL) return NULL;
742 >        if((fgets(line, sizeof(line), f)) == NULL) {
743 >                sg_set_error(SG_ERROR_PARSE, NULL);
744 >                return NULL;
745 >        }
746 >        if((fgets(line, sizeof(line), f)) == NULL) {
747 >                sg_set_error(SG_ERROR_PARSE, NULL);
748 >                return NULL;
749 >        }
750  
751 <        while((fgets(line, sizeof(line), f)) != NULL){
752 <                char *name, *ptr;
753 <                struct ifreq ifr;
754 <                struct ethtool_cmd ethcmd;
755 <                int err;
751 >        while((fgets(line, sizeof(line), f)) != NULL){
752 >                char *name, *ptr;
753 >                struct ifreq ifr;
754 >                struct ethtool_cmd ethcmd;
755 >                int err;
756  
757                  /* Get the interface name */
758 <                ptr = strchr(line, ':');
759 <                if (ptr == NULL) continue;
760 <                *ptr='\0';
761 <                name = line;
762 <                while(isspace(*(name))){
763 <                        name++;
764 <                }
758 >                ptr = strchr(line, ':');
759 >                if (ptr == NULL) continue;
760 >                *ptr='\0';
761 >                name = line;
762 >                while(isspace(*(name))){
763 >                        name++;
764 >                }
765  
766 <                memset(&ifr, 0, sizeof ifr);
767 <                strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
766 >                memset(&ifr, 0, sizeof ifr);
767 >                strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
768  
769                  if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
770                          continue;
# Line 631 | Line 777 | sg_network_iface_stats *sg_get_network_iface_stats(int
777                  network_iface_stat_ptr = network_iface_stats + ifaces;
778                  
779                  if (sg_update_string(&network_iface_stat_ptr->interface_name,
780 <                                     name) == NULL) {
780 >                                     name) < 0) {
781                          return NULL;
782                  }
783                  if ((ifr.ifr_flags & IFF_UP) != 0) {
# Line 640 | Line 786 | sg_network_iface_stats *sg_get_network_iface_stats(int
786                          network_iface_stat_ptr->up = 0;
787                  }
788  
789 <                memset(&ethcmd, 0, sizeof ethcmd);
790 <                ethcmd.cmd = ETHTOOL_GSET;
791 <                ifr.ifr_data = (caddr_t) &ethcmd;
789 >                memset(&ethcmd, 0, sizeof ethcmd);
790 >                ethcmd.cmd = ETHTOOL_GSET;
791 >                ifr.ifr_data = (caddr_t) &ethcmd;
792  
793 <                err = ioctl(sock, SIOCETHTOOL, &ifr);
794 <                if (err == 0) {
793 >                err = ioctl(sock, SIOCETHTOOL, &ifr);
794 >                if (err == 0) {
795                          network_iface_stat_ptr->speed = ethcmd.speed;
796  
797                          switch (ethcmd.duplex) {
798 <                        case 0x00:
799 <                                network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_FULL;
798 >                        case DUPLEX_FULL:
799 >                                network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_FULL;
800                                  break;
801 <                        case 0x01:
802 <                                network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_HALF;
801 >                        case DUPLEX_HALF:
802 >                                network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_HALF;
803                                  break;
804                          default:
805 <                                network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_UNKNOWN;
805 >                                network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_UNKNOWN;
806                          }
807                  } else {
808                          /* Not all interfaces support the ethtool ioctl. */
809                          network_iface_stat_ptr->speed = 0;
810 <                        network_iface_stat_ptr->dup = SG_IFACE_DUPLEX_UNKNOWN;
810 >                        network_iface_stat_ptr->duplex = SG_IFACE_DUPLEX_UNKNOWN;
811                  }
812  
813                  ifaces++;
# Line 669 | Line 815 | sg_network_iface_stats *sg_get_network_iface_stats(int
815          close(sock);
816          fclose(f);
817   #endif
818 + #ifdef CYGWIN
819 +        sg_set_error(SG_ERROR_UNSUPPORTED, "Cygwin");
820 +        return NULL;
821 + #endif
822 + #ifdef HPUX
823 +        sg_set_error(SG_ERROR_UNSUPPORTED, "HP-UX");
824 +        return NULL;
825 + #endif
826 + #ifdef WIN32
827 +        ifaces = 0;
828 +
829 +        if((if_table = win32_get_devices()) == NULL) {
830 +                sg_set_error(SG_ERROR_DEVICES, "network interfaces");
831 +                return NULL;
832 +        }
833 +
834 +        if(VECTOR_RESIZE(network_iface_stats, if_table->dwNumEntries) < 0) {
835 +                free(if_table);
836 +                return NULL;
837 +        }
838 +
839 +        for(i=0; i<if_table->dwNumEntries; i++) {
840 +                network_iface_stat_ptr=network_iface_stats+i;
841 +                if_row = if_table->table[i];
842 +
843 +                if(sg_update_string(&network_iface_stat_ptr->interface_name,
844 +                                        if_row.bDescr) < 0) {
845 +                        free(if_table);
846 +                        return NULL;
847 +                }
848 +                network_iface_stat_ptr->speed = if_row.dwSpeed /1000000;
849 +
850 +                if((if_row.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
851 +                                if_row.dwOperStatus ==
852 +                                        MIB_IF_OPER_STATUS_OPERATIONAL) &&
853 +                                if_row.dwAdminStatus == 1) {
854 +                        network_iface_stat_ptr->up = 1;
855 +                } else {
856 +                        network_iface_stat_ptr->up = 0;
857 +                }
858 +
859 +                ifaces++;
860 +        }
861 +        free(if_table);
862 +
863 +        /* again with the renumbering */
864 +        for (i=0; i<ifaces; i++) {
865 +                no = 2;
866 +                for(j=i+1; j<ifaces; j++) {
867 +                        network_iface_stat_ptr=network_iface_stats+j;
868 +                        if(strcmp(network_iface_stats[i].interface_name,
869 +                                        network_iface_stat_ptr->interface_name) == 0) {
870 +                                if(snprintf(buf, sizeof(buf), " #%d", no) < 0) {
871 +                                        break;
872 +                                }
873 +                                if(sg_concat_string(&network_iface_stat_ptr->interface_name, buf) != 0) {
874 +                                        return NULL;
875 +                                }
876 +
877 +                                no++;
878 +                        }
879 +                }
880 +        }
881 + #endif
882 +
883 + #ifdef SG_ENABLE_DEPRECATED
884 +        network_iface_stat_ptr->dup = network_iface_stat_ptr->duplex;
885 + #endif
886 +
887          *entries = ifaces;
888          return network_iface_stats;
889 + }
890 +
891 + int sg_network_iface_compare_name(const void *va, const void *vb) {
892 +        const sg_network_iface_stats *a = (const sg_network_iface_stats *)va;
893 +        const sg_network_iface_stats *b = (const sg_network_iface_stats *)vb;
894 +
895 +        return strcmp(a->interface_name, b->interface_name);
896   }
897  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines