if_mib.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*-
  2. * Copyright 1996 Massachusetts Institute of Technology
  3. *
  4. * Permission to use, copy, modify, and distribute this software and
  5. * its documentation for any purpose and without fee is hereby
  6. * granted, provided that both the above copyright notice and this
  7. * permission notice appear in all copies, that both the above
  8. * copyright notice and this permission notice appear in all
  9. * supporting documentation, and that the name of M.I.T. not be used
  10. * in advertising or publicity pertaining to distribution of the
  11. * software without specific, written prior permission. M.I.T. makes
  12. * no representations about the suitability of this software for any
  13. * purpose. It is provided "as is" without express or implied
  14. * warranty.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
  17. * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
  18. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
  20. * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  23. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  25. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  26. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. *
  29. * $FreeBSD$
  30. */
  31. #include <sys/param.h>
  32. #include <sys/systm.h>
  33. #include <sys/kernel.h>
  34. #include <sys/malloc.h>
  35. #include <sys/socket.h>
  36. #include <sys/sysctl.h>
  37. #include <net/if.h>
  38. #include <net/if_var.h>
  39. #include <net/if_mib.h>
  40. #include <net/vnet.h>
  41. /*
  42. * A sysctl(3) MIB for generic interface information. This information
  43. * is exported in the net.link.generic branch, which has the following
  44. * structure:
  45. *
  46. * net.link.generic .system - system-wide control variables
  47. * and statistics (node)
  48. * .ifdata.<ifindex>.general
  49. * - what's in `struct ifdata'
  50. * plus some other info
  51. * .ifdata.<ifindex>.linkspecific
  52. * - a link-type-specific data
  53. * structure (as might be used
  54. * by an SNMP agent
  55. *
  56. * Perhaps someday we will make addresses accessible via this interface
  57. * as well (then there will be four such...). The reason that the
  58. * index comes before the last element in the name is because it
  59. * seems more orthogonal that way, particularly with the possibility
  60. * of other per-interface data living down here as well (e.g., integrated
  61. * services stuff).
  62. */
  63. SYSCTL_DECL(_net_link_generic);
  64. static SYSCTL_NODE(_net_link_generic, IFMIB_SYSTEM, system,
  65. CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
  66. "Variables global to all interfaces");
  67. SYSCTL_INT(_net_link_generic_system, IFMIB_IFCOUNT, ifcount,
  68. CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(if_index), 0,
  69. "Number of configured interfaces");
  70. static int
  71. sysctl_ifdata(SYSCTL_HANDLER_ARGS) /* XXX bad syntax! */
  72. {
  73. int *name = (int *)arg1;
  74. int error;
  75. u_int namelen = arg2;
  76. struct ifnet *ifp;
  77. struct ifmibdata ifmd;
  78. struct epoch_tracker et;
  79. size_t dlen;
  80. char *dbuf;
  81. if (namelen != 2)
  82. return EINVAL;
  83. if (name[0] <= 0)
  84. return (ENOENT);
  85. NET_EPOCH_ENTER(et);
  86. ifp = ifnet_byindex_ref(name[0]);
  87. NET_EPOCH_EXIT(et);
  88. if (ifp == NULL)
  89. return (ENOENT);
  90. switch(name[1]) {
  91. default:
  92. error = ENOENT;
  93. goto out;
  94. case IFDATA_GENERAL:
  95. bzero(&ifmd, sizeof(ifmd));
  96. strlcpy(ifmd.ifmd_name, ifp->if_xname, sizeof(ifmd.ifmd_name));
  97. ifmd.ifmd_pcount = ifp->if_pcount;
  98. if_data_copy(ifp, &ifmd.ifmd_data);
  99. ifmd.ifmd_flags = ifp->if_flags | ifp->if_drv_flags;
  100. ifmd.ifmd_snd_len = ifp->if_snd.ifq_len;
  101. ifmd.ifmd_snd_maxlen = ifp->if_snd.ifq_maxlen;
  102. ifmd.ifmd_snd_drops =
  103. ifp->if_get_counter(ifp, IFCOUNTER_OQDROPS);
  104. error = SYSCTL_OUT(req, &ifmd, sizeof ifmd);
  105. if (error)
  106. goto out;
  107. break;
  108. case IFDATA_LINKSPECIFIC:
  109. error = SYSCTL_OUT(req, ifp->if_linkmib, ifp->if_linkmiblen);
  110. if (error || !req->newptr)
  111. goto out;
  112. break;
  113. case IFDATA_DRIVERNAME:
  114. /* 20 is enough for 64bit ints */
  115. dlen = strlen(ifp->if_dname) + 20 + 1;
  116. if ((dbuf = malloc(dlen, M_TEMP, M_NOWAIT)) == NULL) {
  117. error = ENOMEM;
  118. goto out;
  119. }
  120. if (ifp->if_dunit == IF_DUNIT_NONE)
  121. strcpy(dbuf, ifp->if_dname);
  122. else
  123. sprintf(dbuf, "%s%d", ifp->if_dname, ifp->if_dunit);
  124. error = SYSCTL_OUT(req, dbuf, strlen(dbuf) + 1);
  125. if (error == 0 && req->newptr != NULL)
  126. error = EPERM;
  127. free(dbuf, M_TEMP);
  128. goto out;
  129. }
  130. out:
  131. if_rele(ifp);
  132. return error;
  133. }
  134. static SYSCTL_NODE(_net_link_generic, IFMIB_IFDATA, ifdata,
  135. CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_ifdata,
  136. "Interface table");