1 /* 2 * Copyright (c) 2001-2003 3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4 * All rights reserved. 5 * 6 * Author: Harti Brandt <harti@freebsd.org> 7 * 8 * Redistribution of this software and documentation and use in source and 9 * binary forms, with or without modification, are permitted provided that 10 * the following conditions are met: 11 * 12 * 1. Redistributions of source code or documentation must retain the above 13 * copyright notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS 22 * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 23 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 24 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 25 * FRAUNHOFER FOKUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 28 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 31 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $Begemot: bsnmp/snmp_mibII/mibII.h,v 1.12 2003/12/03 10:01:19 hbb Exp $ 34 * 35 * Implementation of the interfaces and IP groups of MIB-II. 36 */ 37 #include <sys/param.h> 38 #include <sys/sysctl.h> 39 #include <sys/socket.h> 40 #include <sys/sockio.h> 41 #include <sys/syslog.h> 42 #include <sys/time.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <errno.h> 47 #include <unistd.h> 48 #include <err.h> 49 #include <ctype.h> 50 #include <net/if.h> 51 #include <net/if_dl.h> 52 #include <net/if_mib.h> 53 #include <net/route.h> 54 #include <netinet/in.h> 55 #include <arpa/inet.h> 56 57 #include "asn1.h" 58 #include "snmp.h" 59 #include "snmpmod.h" 60 #include "snmp_mibII.h" 61 #include "mibII_tree.h" 62 63 64 /* 65 * Interface list and flags. 66 */ 67 TAILQ_HEAD(mibif_list, mibif); 68 enum { 69 MIBIF_FOUND = 0x0001, 70 MIBIF_HIGHSPEED = 0x0002, 71 MIBIF_VERYHIGHSPEED = 0x0004, 72 }; 73 #define hc_inoctets mib.ifmd_data.ifi_ibytes 74 #define hc_outoctets mib.ifmd_data.ifi_obytes 75 #define hc_omcasts mib.ifmd_data.ifi_omcasts 76 #define hc_opackets mib.ifmd_data.ifi_opackets 77 #define hc_imcasts mib.ifmd_data.ifi_imcasts 78 #define hc_ipackets mib.ifmd_data.ifi_ipackets 79 80 /* 81 * Interface addresses. 82 */ 83 TAILQ_HEAD(mibifa_list, mibifa); 84 enum { 85 MIBIFA_FOUND = 0x0001, 86 MIBIFA_DESTROYED = 0x0002, 87 }; 88 89 /* 90 * Receive addresses 91 */ 92 TAILQ_HEAD(mibrcvaddr_list, mibrcvaddr); 93 enum { 94 MIBRCVADDR_FOUND = 0x00010000, 95 }; 96 97 /* 98 * Interface index mapping. The problem here is, that if the same interface 99 * is reinstantiated (for examble by unloading and loading the hardware driver) 100 * we must use the same index for this interface. For dynamic interfaces 101 * (clip, lane) we must use a fresh index, each time a new interface is created. 102 * To differentiate between these types of interfaces we use the following table 103 * which contains an entry for each dynamic interface type. All other interface 104 * types are supposed to be static. The mibindexmap contains an entry for 105 * all interfaces. The mibif pointer is NULL, if the interface doesn't exist 106 * anymore. 107 */ 108 struct mibdynif { 109 SLIST_ENTRY(mibdynif) link; 110 char name[IFNAMSIZ]; 111 }; 112 SLIST_HEAD(mibdynif_list, mibdynif); 113 114 struct mibindexmap { 115 STAILQ_ENTRY(mibindexmap) link; 116 u_short sysindex; 117 u_int ifindex; 118 struct mibif *mibif; /* may be NULL */ 119 char name[IFNAMSIZ]; 120 }; 121 STAILQ_HEAD(mibindexmap_list, mibindexmap); 122 123 /* 124 * Interface stacking. The generic code cannot know how the interfaces stack. 125 * For this reason it instantiates only the x.0 and 0.x table elements. All 126 * others have to be instantiated by the interface specific modules. 127 * The table is read-only. 128 */ 129 struct mibifstack { 130 TAILQ_ENTRY(mibifstack) link; 131 struct asn_oid index; 132 }; 133 TAILQ_HEAD(mibifstack_list, mibifstack); 134 135 /* 136 * NetToMediaTable (ArpTable) 137 */ 138 struct mibarp { 139 TAILQ_ENTRY(mibarp) link; 140 struct asn_oid index; /* contains both the ifindex and addr */ 141 u_char phys[128]; /* the physical address */ 142 u_int physlen; /* and its length */ 143 u_int flags; 144 }; 145 TAILQ_HEAD(mibarp_list, mibarp); 146 enum { 147 MIBARP_FOUND = 0x00010000, 148 MIBARP_PERM = 0x00000001, 149 }; 150 151 /* 152 * New if registrations 153 */ 154 struct newifreg { 155 TAILQ_ENTRY(newifreg) link; 156 const struct lmodule *mod; 157 int (*func)(struct mibif *); 158 }; 159 TAILQ_HEAD(newifreg_list, newifreg); 160 161 /* list of all IP addresses */ 162 extern struct mibifa_list mibifa_list; 163 164 /* list of all interfaces */ 165 extern struct mibif_list mibif_list; 166 167 /* list of dynamic interface names */ 168 extern struct mibdynif_list mibdynif_list; 169 170 /* list of all interface index mappings */ 171 extern struct mibindexmap_list mibindexmap_list; 172 173 /* list of all stacking entries */ 174 extern struct mibifstack_list mibifstack_list; 175 176 /* list of all receive addresses */ 177 extern struct mibrcvaddr_list mibrcvaddr_list; 178 179 /* list of all NetToMedia entries */ 180 extern struct mibarp_list mibarp_list; 181 182 /* number of interfaces */ 183 extern int32_t mib_if_number; 184 185 /* last change of interface table */ 186 extern u_int32_t mib_iftable_last_change; 187 188 /* last change of stack table */ 189 extern u_int32_t mib_ifstack_last_change; 190 191 /* if this is set, one of our lists may be bad. refresh them when idle */ 192 extern int mib_iflist_bad; 193 194 /* last time refreshed */ 195 extern u_int32_t mibarpticks; 196 197 /* info on system clocks */ 198 extern struct clockinfo clockinfo; 199 200 /* get interfaces and interface addresses. */ 201 void mib_fetch_interfaces(void); 202 203 /* check whether this interface(type) is dynamic */ 204 int mib_if_is_dyn(const char *name); 205 206 /* destroy an interface address */ 207 int mib_destroy_ifa(struct mibifa *); 208 209 /* restituate a deleted interface address */ 210 void mib_undestroy_ifa(struct mibifa *); 211 212 /* change interface address */ 213 int mib_modify_ifa(struct mibifa *); 214 215 /* undo if address modification */ 216 void mib_unmodify_ifa(struct mibifa *); 217 218 /* create an interface address */ 219 struct mibifa * mib_create_ifa(u_int ifindex, struct in_addr addr, struct in_addr mask, struct in_addr bcast); 220 221 /* delete a freshly created address */ 222 void mib_uncreate_ifa(struct mibifa *); 223 224 /* create/delete arp entries */ 225 struct mibarp *mib_arp_create(const struct mibif *, struct in_addr, const u_char *, size_t); 226 void mib_arp_delete(struct mibarp *); 227 228 /* find arp entry */ 229 struct mibarp *mib_find_arp(const struct mibif *, struct in_addr); 230 231 /* update arp table */ 232 void mib_arp_update(void); 233 234 /* fetch routing table */ 235 u_char *mib_fetch_rtab(int af, int info, int arg, size_t *lenp); 236 237 /* extract addresses from routing message */ 238 void mib_extract_addrs(int, u_char *, struct sockaddr **); 239