mono-networkinterfaces.c 2.9 KB

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