1122394Sharti/*
2122394Sharti * Copyright (c) 2001-2003
3122394Sharti *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4122394Sharti *	All rights reserved.
5122394Sharti *
6122394Sharti * Author: Harti Brandt <harti@freebsd.org>
7133211Sharti *
8133211Sharti * Redistribution and use in source and binary forms, with or without
9133211Sharti * modification, are permitted provided that the following conditions
10133211Sharti * are met:
11133211Sharti * 1. Redistributions of source code must retain the above copyright
12133211Sharti *    notice, this list of conditions and the following disclaimer.
13122394Sharti * 2. Redistributions in binary form must reproduce the above copyright
14122394Sharti *    notice, this list of conditions and the following disclaimer in the
15122394Sharti *    documentation and/or other materials provided with the distribution.
16133211Sharti *
17133211Sharti * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18133211Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19133211Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20133211Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21133211Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22133211Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23133211Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24133211Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25133211Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26133211Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27133211Sharti * SUCH DAMAGE.
28122394Sharti *
29156066Sharti * $Begemot: bsnmp/snmp_mibII/mibII.h,v 1.16 2006/02/14 09:04:19 brandt_h Exp $
30122394Sharti *
31122394Sharti * Implementation of the interfaces and IP groups of MIB-II.
32122394Sharti */
33122394Sharti#include <sys/param.h>
34122394Sharti#include <sys/sysctl.h>
35122394Sharti#include <sys/socket.h>
36122394Sharti#include <sys/sockio.h>
37122394Sharti#include <sys/syslog.h>
38122394Sharti#include <sys/time.h>
39241654Semax#include <stdint.h>
40122394Sharti#include <stdio.h>
41122394Sharti#include <stdlib.h>
42122394Sharti#include <string.h>
43122394Sharti#include <errno.h>
44122394Sharti#include <unistd.h>
45122394Sharti#include <err.h>
46122394Sharti#include <ctype.h>
47122394Sharti#include <net/if.h>
48122394Sharti#include <net/if_dl.h>
49122394Sharti#include <net/if_mib.h>
50122394Sharti#include <net/route.h>
51122394Sharti#include <netinet/in.h>
52122394Sharti#include <arpa/inet.h>
53122394Sharti
54122394Sharti#include "asn1.h"
55122394Sharti#include "snmp.h"
56122394Sharti#include "snmpmod.h"
57122394Sharti#include "snmp_mibII.h"
58122394Sharti#include "mibII_tree.h"
59122394Sharti
60122394Sharti/*
61122394Sharti * Interface list and flags.
62122394Sharti */
63122394ShartiTAILQ_HEAD(mibif_list, mibif);
64122394Shartienum {
65122394Sharti	MIBIF_FOUND		= 0x0001,
66122394Sharti	MIBIF_HIGHSPEED		= 0x0002,
67122394Sharti	MIBIF_VERYHIGHSPEED	= 0x0004,
68122394Sharti};
69122394Sharti
70122394Sharti/*
71155602Sharti * Private mibif data - hang off from the mibif.
72155602Sharti */
73155602Shartistruct mibif_private {
74155602Sharti	uint64_t	hc_inoctets;
75155602Sharti	uint64_t	hc_outoctets;
76155602Sharti	uint64_t	hc_omcasts;
77155602Sharti	uint64_t	hc_opackets;
78155602Sharti	uint64_t	hc_imcasts;
79155602Sharti	uint64_t	hc_ipackets;
80155602Sharti};
81155602Sharti#define	MIBIF_PRIV(IFP) ((struct mibif_private *)((IFP)->private))
82155602Sharti
83155602Sharti/*
84122394Sharti * Interface addresses.
85122394Sharti */
86122394ShartiTAILQ_HEAD(mibifa_list, mibifa);
87122394Shartienum {
88122394Sharti	MIBIFA_FOUND	 = 0x0001,
89122394Sharti	MIBIFA_DESTROYED = 0x0002,
90122394Sharti};
91122394Sharti
92122394Sharti/*
93122394Sharti * Receive addresses
94122394Sharti */
95122394ShartiTAILQ_HEAD(mibrcvaddr_list, mibrcvaddr);
96122394Shartienum {
97122394Sharti	MIBRCVADDR_FOUND	= 0x00010000,
98122394Sharti};
99122394Sharti
100122394Sharti/*
101122394Sharti * Interface index mapping. The problem here is, that if the same interface
102122394Sharti * is reinstantiated (for examble by unloading and loading the hardware driver)
103122394Sharti * we must use the same index for this interface. For dynamic interfaces
104122394Sharti * (clip, lane) we must use a fresh index, each time a new interface is created.
105122394Sharti * To differentiate between these types of interfaces we use the following table
106122394Sharti * which contains an entry for each dynamic interface type. All other interface
107122394Sharti * types are supposed to be static. The mibindexmap contains an entry for
108122394Sharti * all interfaces. The mibif pointer is NULL, if the interface doesn't exist
109122394Sharti * anymore.
110122394Sharti */
111122394Shartistruct mibdynif {
112122394Sharti	SLIST_ENTRY(mibdynif) link;
113122394Sharti	char	name[IFNAMSIZ];
114122394Sharti};
115122394ShartiSLIST_HEAD(mibdynif_list, mibdynif);
116122394Sharti
117122394Shartistruct mibindexmap {
118122394Sharti	STAILQ_ENTRY(mibindexmap) link;
119122394Sharti	u_short		sysindex;
120122394Sharti	u_int		ifindex;
121122394Sharti	struct mibif	*mibif;		/* may be NULL */
122122394Sharti	char		name[IFNAMSIZ];
123122394Sharti};
124122394ShartiSTAILQ_HEAD(mibindexmap_list, mibindexmap);
125122394Sharti
126122394Sharti/*
127122394Sharti * Interface stacking. The generic code cannot know how the interfaces stack.
128122394Sharti * For this reason it instantiates only the x.0 and 0.x table elements. All
129122394Sharti * others have to be instantiated by the interface specific modules.
130122394Sharti * The table is read-only.
131122394Sharti */
132122394Shartistruct mibifstack {
133122394Sharti	TAILQ_ENTRY(mibifstack) link;
134122394Sharti	struct asn_oid index;
135122394Sharti};
136122394ShartiTAILQ_HEAD(mibifstack_list, mibifstack);
137122394Sharti
138122394Sharti/*
139122394Sharti * NetToMediaTable (ArpTable)
140122394Sharti */
141122394Shartistruct mibarp {
142122394Sharti	TAILQ_ENTRY(mibarp) link;
143122394Sharti	struct asn_oid	index;		/* contains both the ifindex and addr */
144122394Sharti	u_char		phys[128];	/* the physical address */
145122394Sharti	u_int		physlen;	/* and its length */
146122394Sharti	u_int		flags;
147122394Sharti};
148122394ShartiTAILQ_HEAD(mibarp_list, mibarp);
149122394Shartienum {
150122394Sharti	MIBARP_FOUND	= 0x00010000,
151122394Sharti	MIBARP_PERM	= 0x00000001,
152122394Sharti};
153122394Sharti
154122394Sharti/*
155122394Sharti * New if registrations
156122394Sharti */
157122394Shartistruct newifreg {
158122394Sharti	TAILQ_ENTRY(newifreg) link;
159122394Sharti	const struct lmodule *mod;
160122394Sharti	int	(*func)(struct mibif *);
161122394Sharti};
162122394ShartiTAILQ_HEAD(newifreg_list, newifreg);
163122394Sharti
164122394Sharti/* list of all IP addresses */
165122394Shartiextern struct mibifa_list mibifa_list;
166122394Sharti
167122394Sharti/* list of all interfaces */
168122394Shartiextern struct mibif_list mibif_list;
169122394Sharti
170122394Sharti/* list of dynamic interface names */
171122394Shartiextern struct mibdynif_list mibdynif_list;
172122394Sharti
173122394Sharti/* list of all interface index mappings */
174122394Shartiextern struct mibindexmap_list mibindexmap_list;
175122394Sharti
176122394Sharti/* list of all stacking entries */
177122394Shartiextern struct mibifstack_list mibifstack_list;
178122394Sharti
179122394Sharti/* list of all receive addresses */
180122394Shartiextern struct mibrcvaddr_list mibrcvaddr_list;
181122394Sharti
182122394Sharti/* list of all NetToMedia entries */
183122394Shartiextern struct mibarp_list mibarp_list;
184122394Sharti
185122394Sharti/* number of interfaces */
186122394Shartiextern int32_t mib_if_number;
187122394Sharti
188122394Sharti/* last change of interface table */
189146525Shartiextern uint64_t mib_iftable_last_change;
190122394Sharti
191122394Sharti/* last change of stack table */
192146525Shartiextern uint64_t mib_ifstack_last_change;
193122394Sharti
194122394Sharti/* if this is set, one of our lists may be bad. refresh them when idle */
195122394Shartiextern int mib_iflist_bad;
196122394Sharti
197122394Sharti/* last time refreshed */
198146525Shartiextern uint64_t mibarpticks;
199122394Sharti
200122394Sharti/* info on system clocks */
201122394Shartiextern struct clockinfo clockinfo;
202122394Sharti
203155602Sharti/* baud rate of fastest interface */
204155602Shartiextern uint64_t mibif_maxspeed;
205155602Sharti
206155602Sharti/* user-forced update interval */
207155602Shartiextern u_int mibif_force_hc_update_interval;
208155602Sharti
209155602Sharti/* current update interval */
210155602Shartiextern u_int mibif_hc_update_interval;
211155602Sharti
212155602Sharti/* re-compute update interval */
213155602Shartivoid mibif_reset_hc_timer(void);
214155602Sharti
215200063Ssyrinx/* interfaces' data poll interval */
216200063Ssyrinxextern u_int mibII_poll_ticks;
217200063Ssyrinx
218200063Ssyrinx/* restart the data poll timer */
219200063Ssyrinxvoid mibif_restart_mibII_poll_timer(void);
220200063Ssyrinx
221200063Ssyrinx#define MIBII_POLL_TICKS	100
222200063Ssyrinx
223122394Sharti/* get interfaces and interface addresses. */
224122394Shartivoid mib_fetch_interfaces(void);
225122394Sharti
226122394Sharti/* check whether this interface(type) is dynamic */
227122394Shartiint mib_if_is_dyn(const char *name);
228122394Sharti
229122394Sharti/* destroy an interface address */
230122394Shartiint mib_destroy_ifa(struct mibifa *);
231122394Sharti
232122394Sharti/* restituate a deleted interface address */
233122394Shartivoid mib_undestroy_ifa(struct mibifa *);
234122394Sharti
235122394Sharti/* change interface address */
236122394Shartiint mib_modify_ifa(struct mibifa *);
237122394Sharti
238122394Sharti/* undo if address modification */
239122394Shartivoid mib_unmodify_ifa(struct mibifa *);
240122394Sharti
241122394Sharti/* create an interface address */
242122394Shartistruct mibifa * mib_create_ifa(u_int ifindex, struct in_addr addr, struct in_addr mask, struct in_addr bcast);
243122394Sharti
244122394Sharti/* delete a freshly created address */
245122394Shartivoid mib_uncreate_ifa(struct mibifa *);
246122394Sharti
247122394Sharti/* create/delete arp entries */
248122394Shartistruct mibarp *mib_arp_create(const struct mibif *, struct in_addr, const u_char *, size_t);
249122394Shartivoid mib_arp_delete(struct mibarp *);
250122394Sharti
251122394Sharti/* find arp entry */
252122394Shartistruct mibarp *mib_find_arp(const struct mibif *, struct in_addr);
253122394Sharti
254122394Sharti/* update arp table */
255122394Shartivoid mib_arp_update(void);
256122394Sharti
257122394Sharti/* fetch routing table */
258122394Shartiu_char *mib_fetch_rtab(int af, int info, int arg, size_t *lenp);
259122394Sharti
260150920Sharti/* process routing message */
261150920Shartivoid mib_sroute_process(struct rt_msghdr *, struct sockaddr *,
262150920Sharti    struct sockaddr *, struct sockaddr *);
263150920Sharti
264150920Sharti/* send a routing message */
265150920Shartivoid mib_send_rtmsg(struct rt_msghdr *, struct sockaddr *,
266150920Sharti    struct sockaddr *, struct sockaddr *);
267150920Sharti
268122394Sharti/* extract addresses from routing message */
269122394Shartivoid mib_extract_addrs(int, u_char *, struct sockaddr **);
270150920Sharti
271150920Sharti/* fetch routing table */
272150920Shartiint mib_fetch_route(void);
273