/*1* Copyright (c) 2001-20032* Fraunhofer Institute for Open Communication Systems (FhG Fokus).3* All rights reserved.4*5* Author: Harti Brandt <[email protected]>6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*28* $Begemot: bsnmp/snmp_mibII/mibII.h,v 1.16 2006/02/14 09:04:19 brandt_h Exp $29*30* Implementation of the interfaces and IP groups of MIB-II.31*/32#include <sys/param.h>33#include <sys/sysctl.h>34#include <sys/socket.h>35#include <sys/sockio.h>36#include <sys/syslog.h>37#include <stdint.h>38#include <stdio.h>39#include <stdlib.h>40#include <string.h>41#include <errno.h>42#include <unistd.h>43#include <err.h>44#include <ctype.h>45#include <net/if.h>46#include <net/if_dl.h>47#include <net/if_mib.h>48#include <net/route.h>49#include <netinet/in.h>50#include <arpa/inet.h>5152#include "asn1.h"53#include "snmp.h"54#include "snmpmod.h"55#include "snmp_mibII.h"56#include "mibII_tree.h"5758/* maximum size of interface alias unless overridden with net.ifdescr_maxlen */59#define MIBIF_ALIAS_SIZE (64 + 1)60#define MIBIF_ALIAS_SIZE_MAX 10246162/*63* Interface list and flags.64*/65TAILQ_HEAD(mibif_list, mibif);66enum {67MIBIF_FOUND = 0x0001,68MIBIF_HIGHSPEED = 0x0002,69MIBIF_VERYHIGHSPEED = 0x0004,70};7172/*73* Private mibif data - hang off from the mibif.74*/75struct mibif_private {76uint64_t hc_inoctets;77uint64_t hc_outoctets;78uint64_t hc_omcasts;79uint64_t hc_opackets;80uint64_t hc_imcasts;81uint64_t hc_ipackets;82};83#define MIBIF_PRIV(IFP) ((struct mibif_private *)((IFP)->private))8485/*86* Interface addresses.87*/88TAILQ_HEAD(mibifa_list, mibifa);89enum {90MIBIFA_FOUND = 0x0001,91MIBIFA_DESTROYED = 0x0002,92};9394/*95* Receive addresses96*/97TAILQ_HEAD(mibrcvaddr_list, mibrcvaddr);98enum {99MIBRCVADDR_FOUND = 0x00010000,100};101102/*103* Interface index mapping. The problem here is, that if the same interface104* is reinstantiated (for examble by unloading and loading the hardware driver)105* we must use the same index for this interface. For dynamic interfaces106* (clip, lane) we must use a fresh index, each time a new interface is created.107* To differentiate between these types of interfaces we use the following table108* which contains an entry for each dynamic interface type. All other interface109* types are supposed to be static. The mibindexmap contains an entry for110* all interfaces. The mibif pointer is NULL, if the interface doesn't exist111* anymore.112*/113struct mibdynif {114SLIST_ENTRY(mibdynif) link;115char name[IFNAMSIZ];116};117SLIST_HEAD(mibdynif_list, mibdynif);118119struct mibindexmap {120STAILQ_ENTRY(mibindexmap) link;121u_short sysindex;122u_int ifindex;123struct mibif *mibif; /* may be NULL */124char name[IFNAMSIZ];125};126STAILQ_HEAD(mibindexmap_list, mibindexmap);127128/*129* Interface stacking. The generic code cannot know how the interfaces stack.130* For this reason it instantiates only the x.0 and 0.x table elements. All131* others have to be instantiated by the interface specific modules.132* The table is read-only.133*/134struct mibifstack {135TAILQ_ENTRY(mibifstack) link;136struct asn_oid index;137};138TAILQ_HEAD(mibifstack_list, mibifstack);139140/*141* NetToMediaTable (ArpTable)142*/143struct mibarp {144TAILQ_ENTRY(mibarp) link;145struct asn_oid index; /* contains both the ifindex and addr */146u_char phys[128]; /* the physical address */147u_int physlen; /* and its length */148u_int flags;149};150TAILQ_HEAD(mibarp_list, mibarp);151enum {152MIBARP_FOUND = 0x00010000,153MIBARP_PERM = 0x00000001,154};155156/*157* New if registrations158*/159struct newifreg {160TAILQ_ENTRY(newifreg) link;161const struct lmodule *mod;162int (*func)(struct mibif *);163};164TAILQ_HEAD(newifreg_list, newifreg);165166/* list of all IP addresses */167extern struct mibifa_list mibifa_list;168169/* list of all interfaces */170extern struct mibif_list mibif_list;171172/* list of dynamic interface names */173extern struct mibdynif_list mibdynif_list;174175/* list of all interface index mappings */176extern struct mibindexmap_list mibindexmap_list;177178/* list of all stacking entries */179extern struct mibifstack_list mibifstack_list;180181/* list of all receive addresses */182extern struct mibrcvaddr_list mibrcvaddr_list;183184/* list of all NetToMedia entries */185extern struct mibarp_list mibarp_list;186187/* number of interfaces */188extern int32_t mib_if_number;189190/* last change of interface table */191extern uint64_t mib_iftable_last_change;192193/* last change of stack table */194extern uint64_t mib_ifstack_last_change;195196/* if this is set, one of our lists may be bad. refresh them when idle */197extern int mib_iflist_bad;198199/* last time refreshed */200extern uint64_t mibarpticks;201202/* baud rate of fastest interface */203extern uint64_t mibif_maxspeed;204205/* user-forced update interval */206extern u_int mibif_force_hc_update_interval;207208/* current update interval */209extern u_int mibif_hc_update_interval;210211/* re-compute update interval */212void mibif_reset_hc_timer(void);213214/* interfaces' data poll interval */215extern u_int mibII_poll_ticks;216217/* restart the data poll timer */218void mibif_restart_mibII_poll_timer(void);219220#define MIBII_POLL_TICKS 100221222/* get interfaces and interface addresses. */223void mib_fetch_interfaces(void);224225/* check whether this interface(type) is dynamic */226int mib_if_is_dyn(const char *name);227228/* destroy an interface address */229int mib_destroy_ifa(struct mibifa *);230231/* restituate a deleted interface address */232void mib_undestroy_ifa(struct mibifa *);233234/* change interface address */235int mib_modify_ifa(struct mibifa *);236237/* undo if address modification */238void mib_unmodify_ifa(struct mibifa *);239240/* create an interface address */241struct mibifa * mib_create_ifa(u_int ifindex, struct in_addr addr, struct in_addr mask, struct in_addr bcast);242243/* delete a freshly created address */244void mib_uncreate_ifa(struct mibifa *);245246/* create/delete arp entries */247struct mibarp *mib_arp_create(const struct mibif *, struct in_addr, const u_char *, size_t);248void mib_arp_delete(struct mibarp *);249250/* find arp entry */251struct mibarp *mib_find_arp(const struct mibif *, struct in_addr);252253/* update arp table */254void mib_arp_update(void);255256/* fetch routing table */257u_char *mib_fetch_rtab(int af, int info, int arg, size_t *lenp);258259/* process routing message */260void mib_sroute_process(struct rt_msghdr *, struct sockaddr *,261struct sockaddr *, struct sockaddr *);262263/* send a routing message */264void mib_send_rtmsg(struct rt_msghdr *, struct sockaddr *,265struct sockaddr *, struct sockaddr *);266267/* extract addresses from routing message */268void mib_extract_addrs(int, u_char *, struct sockaddr **);269270/* fetch routing table */271int mib_fetch_route(void);272273274