Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / utils / mono-networkinterfaces.c
1 /**
2  * \file
3  */
4
5 #include "config.h"
6 #include "utils/mono-networkinterfaces.h"
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 /* FIXME: bsds untested */
13
14 /**
15  * mono_networkinterface_list:
16  * \param size a pointer to a location where the size of the returned array is stored
17  * \returns an array of names for the interfaces currently on the system.
18  * The size of the array is stored in \p size.
19  */
20 gpointer*
21 mono_networkinterface_list (int *size)
22 {
23         int i = 0, count = 0;
24         void **nilist = NULL;
25         char buf [512];
26         FILE *f;
27         char name [256];
28
29         f = fopen ("/proc/net/dev", "r");
30         if (!f) 
31                 return NULL;
32
33         if (!fgets (buf, sizeof (buf) / sizeof (char), f))
34                 goto out;
35
36         if (!fgets (buf, sizeof (buf) / sizeof (char), f))
37                 goto out;
38
39         while (fgets (buf, sizeof (buf), f) != NULL) {
40                 char *ptr;
41                 buf [sizeof(buf) - 1] = 0;
42                 if ((ptr = strchr (buf, ':')) == NULL || (*ptr++ = 0, sscanf (buf, "%s", name) != 1))
43                         goto out;
44
45                 if (i >= count) {
46                         if (!count)
47                                 count = 16;
48                         else
49                                 count *= 2;
50                 }
51
52                 nilist = (void **) g_realloc (nilist, count * sizeof (void*));
53                 nilist [i++] = g_strdup (name);
54         }
55
56  out:
57         if (f) fclose(f);
58         if (size)
59                 *size = i;
60
61         if (!nilist)
62                 nilist = (void **) g_malloc (sizeof (void*));
63         nilist [i] = NULL;
64         return nilist;
65 }
66
67 /**
68  * mono_network_get_data:
69  * \param name name of the interface
70  * \param data description of data to return
71  * \return a data item of a network adapter like bytes sent per sec, etc
72  * according to the \p data argumet.
73  */
74 gint64
75 mono_network_get_data (char* name, MonoNetworkData data, MonoNetworkError *error)
76 {
77         gint64 val = 0;
78         char buf [512];
79         char cname [256];
80         FILE *f;
81
82         unsigned long rx_bytes, rx_packets, rx_errs, rx_drops,
83                 rx_fifo, rx_frame, tx_bytes, tx_packets, tx_errs, tx_drops,
84                 tx_fifo, tx_colls, tx_carrier, rx_multi;
85
86         *error = MONO_NETWORK_ERROR_OTHER;
87
88         f = fopen ("/proc/net/dev", "r");
89         if (!f) 
90                 return -1;
91
92         if (!fgets (buf, sizeof (buf) / sizeof (char), f))
93                 goto out;
94
95         if (!fgets (buf, sizeof (buf) / sizeof (char), f))
96                 goto out;
97
98         while (fgets (buf, sizeof (buf), f) != NULL) {
99
100                 char *ptr;
101                 buf [sizeof (buf) - 1] = 0;
102                 if ((ptr = strchr (buf, ':')) == NULL ||
103                                 (*ptr++ = 0, sscanf (buf, "%250s", cname) != 1))
104                         goto out;
105
106                 if (strcmp (name, cname) != 0) continue;
107
108                 if (sscanf (ptr, "%ld%ld%ld%ld%ld%ld%ld%*d%ld%ld%ld%ld%ld%ld%ld",
109                                                          &rx_bytes, &rx_packets, &rx_errs, &rx_drops,
110                                                          &rx_fifo, &rx_frame, &rx_multi,
111                                                          &tx_bytes, &tx_packets, &tx_errs, &tx_drops,
112                                                          &tx_fifo, &tx_colls, &tx_carrier) != 14) 
113                         goto out;
114
115                 switch (data) {
116                 case MONO_NETWORK_BYTESSENT:
117                         val = tx_bytes;
118                         *error = MONO_NETWORK_ERROR_NONE;
119                         goto out;
120                 case MONO_NETWORK_BYTESREC:
121                         val = rx_bytes;
122                         *error = MONO_NETWORK_ERROR_NONE;
123                         goto out;
124                 case MONO_NETWORK_BYTESTOTAL:
125                         val = rx_bytes + tx_bytes;
126                         *error = MONO_NETWORK_ERROR_NONE;
127                         goto out;
128                 }
129         }
130
131  out:
132         if (f) fclose (f);
133         return val;
134 }
135