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