1f06ca4afSHartmut Brandt /* 2f06ca4afSHartmut Brandt * Copyright (c) 2001-2003 3f06ca4afSHartmut Brandt * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4f06ca4afSHartmut Brandt * All rights reserved. 5f06ca4afSHartmut Brandt * 6f06ca4afSHartmut Brandt * Author: Harti Brandt <harti@freebsd.org> 7f06ca4afSHartmut Brandt * 8896052c1SHartmut Brandt * Redistribution and use in source and binary forms, with or without 9896052c1SHartmut Brandt * modification, are permitted provided that the following conditions 10896052c1SHartmut Brandt * are met: 11896052c1SHartmut Brandt * 1. Redistributions of source code must retain the above copyright 12896052c1SHartmut Brandt * notice, this list of conditions and the following disclaimer. 13f06ca4afSHartmut Brandt * 2. Redistributions in binary form must reproduce the above copyright 14f06ca4afSHartmut Brandt * notice, this list of conditions and the following disclaimer in the 15f06ca4afSHartmut Brandt * documentation and/or other materials provided with the distribution. 16f06ca4afSHartmut Brandt * 17896052c1SHartmut Brandt * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18896052c1SHartmut Brandt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19896052c1SHartmut Brandt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20896052c1SHartmut Brandt * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 21896052c1SHartmut Brandt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22896052c1SHartmut Brandt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23896052c1SHartmut Brandt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24896052c1SHartmut Brandt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25896052c1SHartmut Brandt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26896052c1SHartmut Brandt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27896052c1SHartmut Brandt * SUCH DAMAGE. 28f06ca4afSHartmut Brandt * 29748b5b1eSHartmut Brandt * $Begemot: bsnmp/snmp_mibII/mibII.h,v 1.16 2006/02/14 09:04:19 brandt_h Exp $ 30f06ca4afSHartmut Brandt * 31f06ca4afSHartmut Brandt * Implementation of the interfaces and IP groups of MIB-II. 32f06ca4afSHartmut Brandt */ 33f06ca4afSHartmut Brandt #include <sys/param.h> 34f06ca4afSHartmut Brandt #include <sys/sysctl.h> 35f06ca4afSHartmut Brandt #include <sys/socket.h> 36f06ca4afSHartmut Brandt #include <sys/sockio.h> 37f06ca4afSHartmut Brandt #include <sys/syslog.h> 38f06ca4afSHartmut Brandt #include <sys/time.h> 39aa21cf78SMaksim Yevmenkin #include <stdint.h> 40f06ca4afSHartmut Brandt #include <stdio.h> 41f06ca4afSHartmut Brandt #include <stdlib.h> 42f06ca4afSHartmut Brandt #include <string.h> 43f06ca4afSHartmut Brandt #include <errno.h> 44f06ca4afSHartmut Brandt #include <unistd.h> 45f06ca4afSHartmut Brandt #include <err.h> 46f06ca4afSHartmut Brandt #include <ctype.h> 47f06ca4afSHartmut Brandt #include <net/if.h> 48f06ca4afSHartmut Brandt #include <net/if_dl.h> 49f06ca4afSHartmut Brandt #include <net/if_mib.h> 50f06ca4afSHartmut Brandt #include <net/route.h> 51f06ca4afSHartmut Brandt #include <netinet/in.h> 52f06ca4afSHartmut Brandt #include <arpa/inet.h> 53f06ca4afSHartmut Brandt 54f06ca4afSHartmut Brandt #include "asn1.h" 55f06ca4afSHartmut Brandt #include "snmp.h" 56f06ca4afSHartmut Brandt #include "snmpmod.h" 57f06ca4afSHartmut Brandt #include "snmp_mibII.h" 58f06ca4afSHartmut Brandt #include "mibII_tree.h" 59f06ca4afSHartmut Brandt 601a498d2eSEugene Grosbein /* maximum size of interface alias unless overridden with net.ifdescr_maxlen */ 6154902c0aSBjoern A. Zeeb #define MIBIF_ALIAS_SIZE (64 + 1) 621a498d2eSEugene Grosbein #define MIBIF_ALIAS_SIZE_MAX 1024 635edd0d3aSHartmut Brandt 64f06ca4afSHartmut Brandt /* 65f06ca4afSHartmut Brandt * Interface list and flags. 66f06ca4afSHartmut Brandt */ 67f06ca4afSHartmut Brandt TAILQ_HEAD(mibif_list, mibif); 68f06ca4afSHartmut Brandt enum { 69f06ca4afSHartmut Brandt MIBIF_FOUND = 0x0001, 70f06ca4afSHartmut Brandt MIBIF_HIGHSPEED = 0x0002, 71f06ca4afSHartmut Brandt MIBIF_VERYHIGHSPEED = 0x0004, 72f06ca4afSHartmut Brandt }; 73c6a4e658SHartmut Brandt 74c6a4e658SHartmut Brandt /* 75c6a4e658SHartmut Brandt * Private mibif data - hang off from the mibif. 76c6a4e658SHartmut Brandt */ 77c6a4e658SHartmut Brandt struct mibif_private { 78c6a4e658SHartmut Brandt uint64_t hc_inoctets; 79c6a4e658SHartmut Brandt uint64_t hc_outoctets; 80c6a4e658SHartmut Brandt uint64_t hc_omcasts; 81c6a4e658SHartmut Brandt uint64_t hc_opackets; 82c6a4e658SHartmut Brandt uint64_t hc_imcasts; 83c6a4e658SHartmut Brandt uint64_t hc_ipackets; 845edd0d3aSHartmut Brandt }; 85c6a4e658SHartmut Brandt #define MIBIF_PRIV(IFP) ((struct mibif_private *)((IFP)->private)) 86c6a4e658SHartmut Brandt 87f06ca4afSHartmut Brandt /* 88f06ca4afSHartmut Brandt * Interface addresses. 89f06ca4afSHartmut Brandt */ 90f06ca4afSHartmut Brandt TAILQ_HEAD(mibifa_list, mibifa); 91f06ca4afSHartmut Brandt enum { 92f06ca4afSHartmut Brandt MIBIFA_FOUND = 0x0001, 93f06ca4afSHartmut Brandt MIBIFA_DESTROYED = 0x0002, 94f06ca4afSHartmut Brandt }; 95f06ca4afSHartmut Brandt 96f06ca4afSHartmut Brandt /* 97f06ca4afSHartmut Brandt * Receive addresses 98f06ca4afSHartmut Brandt */ 99f06ca4afSHartmut Brandt TAILQ_HEAD(mibrcvaddr_list, mibrcvaddr); 100f06ca4afSHartmut Brandt enum { 101f06ca4afSHartmut Brandt MIBRCVADDR_FOUND = 0x00010000, 102f06ca4afSHartmut Brandt }; 103f06ca4afSHartmut Brandt 104f06ca4afSHartmut Brandt /* 105f06ca4afSHartmut Brandt * Interface index mapping. The problem here is, that if the same interface 106f06ca4afSHartmut Brandt * is reinstantiated (for examble by unloading and loading the hardware driver) 107f06ca4afSHartmut Brandt * we must use the same index for this interface. For dynamic interfaces 108f06ca4afSHartmut Brandt * (clip, lane) we must use a fresh index, each time a new interface is created. 109f06ca4afSHartmut Brandt * To differentiate between these types of interfaces we use the following table 110f06ca4afSHartmut Brandt * which contains an entry for each dynamic interface type. All other interface 111f06ca4afSHartmut Brandt * types are supposed to be static. The mibindexmap contains an entry for 112f06ca4afSHartmut Brandt * all interfaces. The mibif pointer is NULL, if the interface doesn't exist 113f06ca4afSHartmut Brandt * anymore. 114f06ca4afSHartmut Brandt */ 115f06ca4afSHartmut Brandt struct mibdynif { 116f06ca4afSHartmut Brandt SLIST_ENTRY(mibdynif) link; 117f06ca4afSHartmut Brandt char name[IFNAMSIZ]; 118f06ca4afSHartmut Brandt }; 119f06ca4afSHartmut Brandt SLIST_HEAD(mibdynif_list, mibdynif); 120f06ca4afSHartmut Brandt 121f06ca4afSHartmut Brandt struct mibindexmap { 122f06ca4afSHartmut Brandt STAILQ_ENTRY(mibindexmap) link; 123f06ca4afSHartmut Brandt u_short sysindex; 124f06ca4afSHartmut Brandt u_int ifindex; 125f06ca4afSHartmut Brandt struct mibif *mibif; /* may be NULL */ 126f06ca4afSHartmut Brandt char name[IFNAMSIZ]; 127f06ca4afSHartmut Brandt }; 128f06ca4afSHartmut Brandt STAILQ_HEAD(mibindexmap_list, mibindexmap); 129f06ca4afSHartmut Brandt 130f06ca4afSHartmut Brandt /* 131f06ca4afSHartmut Brandt * Interface stacking. The generic code cannot know how the interfaces stack. 132f06ca4afSHartmut Brandt * For this reason it instantiates only the x.0 and 0.x table elements. All 133f06ca4afSHartmut Brandt * others have to be instantiated by the interface specific modules. 134f06ca4afSHartmut Brandt * The table is read-only. 135f06ca4afSHartmut Brandt */ 136f06ca4afSHartmut Brandt struct mibifstack { 137f06ca4afSHartmut Brandt TAILQ_ENTRY(mibifstack) link; 138f06ca4afSHartmut Brandt struct asn_oid index; 139f06ca4afSHartmut Brandt }; 140f06ca4afSHartmut Brandt TAILQ_HEAD(mibifstack_list, mibifstack); 141f06ca4afSHartmut Brandt 142f06ca4afSHartmut Brandt /* 143f06ca4afSHartmut Brandt * NetToMediaTable (ArpTable) 144f06ca4afSHartmut Brandt */ 145f06ca4afSHartmut Brandt struct mibarp { 146f06ca4afSHartmut Brandt TAILQ_ENTRY(mibarp) link; 147f06ca4afSHartmut Brandt struct asn_oid index; /* contains both the ifindex and addr */ 148f06ca4afSHartmut Brandt u_char phys[128]; /* the physical address */ 149f06ca4afSHartmut Brandt u_int physlen; /* and its length */ 150f06ca4afSHartmut Brandt u_int flags; 151f06ca4afSHartmut Brandt }; 152f06ca4afSHartmut Brandt TAILQ_HEAD(mibarp_list, mibarp); 153f06ca4afSHartmut Brandt enum { 154f06ca4afSHartmut Brandt MIBARP_FOUND = 0x00010000, 155f06ca4afSHartmut Brandt MIBARP_PERM = 0x00000001, 156f06ca4afSHartmut Brandt }; 157f06ca4afSHartmut Brandt 158f06ca4afSHartmut Brandt /* 159f06ca4afSHartmut Brandt * New if registrations 160f06ca4afSHartmut Brandt */ 161f06ca4afSHartmut Brandt struct newifreg { 162f06ca4afSHartmut Brandt TAILQ_ENTRY(newifreg) link; 163f06ca4afSHartmut Brandt const struct lmodule *mod; 164f06ca4afSHartmut Brandt int (*func)(struct mibif *); 165f06ca4afSHartmut Brandt }; 166f06ca4afSHartmut Brandt TAILQ_HEAD(newifreg_list, newifreg); 167f06ca4afSHartmut Brandt 168f06ca4afSHartmut Brandt /* list of all IP addresses */ 169f06ca4afSHartmut Brandt extern struct mibifa_list mibifa_list; 170f06ca4afSHartmut Brandt 171f06ca4afSHartmut Brandt /* list of all interfaces */ 172f06ca4afSHartmut Brandt extern struct mibif_list mibif_list; 173f06ca4afSHartmut Brandt 174f06ca4afSHartmut Brandt /* list of dynamic interface names */ 175f06ca4afSHartmut Brandt extern struct mibdynif_list mibdynif_list; 176f06ca4afSHartmut Brandt 177f06ca4afSHartmut Brandt /* list of all interface index mappings */ 178f06ca4afSHartmut Brandt extern struct mibindexmap_list mibindexmap_list; 179f06ca4afSHartmut Brandt 180f06ca4afSHartmut Brandt /* list of all stacking entries */ 181f06ca4afSHartmut Brandt extern struct mibifstack_list mibifstack_list; 182f06ca4afSHartmut Brandt 183f06ca4afSHartmut Brandt /* list of all receive addresses */ 184f06ca4afSHartmut Brandt extern struct mibrcvaddr_list mibrcvaddr_list; 185f06ca4afSHartmut Brandt 186f06ca4afSHartmut Brandt /* list of all NetToMedia entries */ 187f06ca4afSHartmut Brandt extern struct mibarp_list mibarp_list; 188f06ca4afSHartmut Brandt 189f06ca4afSHartmut Brandt /* number of interfaces */ 190f06ca4afSHartmut Brandt extern int32_t mib_if_number; 191f06ca4afSHartmut Brandt 192f06ca4afSHartmut Brandt /* last change of interface table */ 193f06ca4afSHartmut Brandt extern uint64_t mib_iftable_last_change; 19469292cedSHartmut Brandt 195f06ca4afSHartmut Brandt /* last change of stack table */ 196f06ca4afSHartmut Brandt extern uint64_t mib_ifstack_last_change; 19769292cedSHartmut Brandt 198f06ca4afSHartmut Brandt /* if this is set, one of our lists may be bad. refresh them when idle */ 199f06ca4afSHartmut Brandt extern int mib_iflist_bad; 200f06ca4afSHartmut Brandt 201f06ca4afSHartmut Brandt /* last time refreshed */ 202f06ca4afSHartmut Brandt extern uint64_t mibarpticks; 20369292cedSHartmut Brandt 204f06ca4afSHartmut Brandt /* info on system clocks */ 205f06ca4afSHartmut Brandt extern struct clockinfo clockinfo; 206f06ca4afSHartmut Brandt 207f06ca4afSHartmut Brandt /* baud rate of fastest interface */ 208c6a4e658SHartmut Brandt extern uint64_t mibif_maxspeed; 209c6a4e658SHartmut Brandt 210c6a4e658SHartmut Brandt /* user-forced update interval */ 211c6a4e658SHartmut Brandt extern u_int mibif_force_hc_update_interval; 212c6a4e658SHartmut Brandt 213c6a4e658SHartmut Brandt /* current update interval */ 214c6a4e658SHartmut Brandt extern u_int mibif_hc_update_interval; 215c6a4e658SHartmut Brandt 216c6a4e658SHartmut Brandt /* re-compute update interval */ 217c6a4e658SHartmut Brandt void mibif_reset_hc_timer(void); 218c6a4e658SHartmut Brandt 219c6a4e658SHartmut Brandt /* interfaces' data poll interval */ 220bd96183dSShteryana Shopova extern u_int mibII_poll_ticks; 221bd96183dSShteryana Shopova 222bd96183dSShteryana Shopova /* restart the data poll timer */ 223bd96183dSShteryana Shopova void mibif_restart_mibII_poll_timer(void); 224bd96183dSShteryana Shopova 225bd96183dSShteryana Shopova #define MIBII_POLL_TICKS 100 226bd96183dSShteryana Shopova 227bd96183dSShteryana Shopova /* get interfaces and interface addresses. */ 228f06ca4afSHartmut Brandt void mib_fetch_interfaces(void); 229f06ca4afSHartmut Brandt 230f06ca4afSHartmut Brandt /* check whether this interface(type) is dynamic */ 231f06ca4afSHartmut Brandt int mib_if_is_dyn(const char *name); 232f06ca4afSHartmut Brandt 233f06ca4afSHartmut Brandt /* destroy an interface address */ 234f06ca4afSHartmut Brandt int mib_destroy_ifa(struct mibifa *); 235f06ca4afSHartmut Brandt 236f06ca4afSHartmut Brandt /* restituate a deleted interface address */ 237f06ca4afSHartmut Brandt void mib_undestroy_ifa(struct mibifa *); 238f06ca4afSHartmut Brandt 239f06ca4afSHartmut Brandt /* change interface address */ 240f06ca4afSHartmut Brandt int mib_modify_ifa(struct mibifa *); 241f06ca4afSHartmut Brandt 242f06ca4afSHartmut Brandt /* undo if address modification */ 243f06ca4afSHartmut Brandt void mib_unmodify_ifa(struct mibifa *); 244f06ca4afSHartmut Brandt 245f06ca4afSHartmut Brandt /* create an interface address */ 246f06ca4afSHartmut Brandt struct mibifa * mib_create_ifa(u_int ifindex, struct in_addr addr, struct in_addr mask, struct in_addr bcast); 247f06ca4afSHartmut Brandt 248f06ca4afSHartmut Brandt /* delete a freshly created address */ 249f06ca4afSHartmut Brandt void mib_uncreate_ifa(struct mibifa *); 250f06ca4afSHartmut Brandt 251f06ca4afSHartmut Brandt /* create/delete arp entries */ 252f06ca4afSHartmut Brandt struct mibarp *mib_arp_create(const struct mibif *, struct in_addr, const u_char *, size_t); 253f06ca4afSHartmut Brandt void mib_arp_delete(struct mibarp *); 254f06ca4afSHartmut Brandt 255f06ca4afSHartmut Brandt /* find arp entry */ 256f06ca4afSHartmut Brandt struct mibarp *mib_find_arp(const struct mibif *, struct in_addr); 257f06ca4afSHartmut Brandt 258f06ca4afSHartmut Brandt /* update arp table */ 259f06ca4afSHartmut Brandt void mib_arp_update(void); 260f06ca4afSHartmut Brandt 261f06ca4afSHartmut Brandt /* fetch routing table */ 262f06ca4afSHartmut Brandt u_char *mib_fetch_rtab(int af, int info, int arg, size_t *lenp); 263f06ca4afSHartmut Brandt 264f06ca4afSHartmut Brandt /* process routing message */ 265165c5d31SHartmut Brandt void mib_sroute_process(struct rt_msghdr *, struct sockaddr *, 266165c5d31SHartmut Brandt struct sockaddr *, struct sockaddr *); 267165c5d31SHartmut Brandt 268165c5d31SHartmut Brandt /* send a routing message */ 269165c5d31SHartmut Brandt void mib_send_rtmsg(struct rt_msghdr *, struct sockaddr *, 270165c5d31SHartmut Brandt struct sockaddr *, struct sockaddr *); 271165c5d31SHartmut Brandt 272165c5d31SHartmut Brandt /* extract addresses from routing message */ 273f06ca4afSHartmut Brandt void mib_extract_addrs(int, u_char *, struct sockaddr **); 274f06ca4afSHartmut Brandt 275165c5d31SHartmut Brandt /* fetch routing table */ 276165c5d31SHartmut Brandt int mib_fetch_route(void); 277165c5d31SHartmut Brandt