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>
7310901Sngie *
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.
16310901Sngie *
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 *
29133211Sharti * $Begemot: bsnmp/snmp_mibII/mibII_rcvaddr.c,v 1.9 2004/08/06 08:47:03 brandt Exp $
30122394Sharti *
31122394Sharti * Interface receive address table.
32122394Sharti */
33122394Sharti#include "mibII.h"
34122394Sharti#include "mibII_oid.h"
35122394Sharti
36122394Sharti/*
37122394Sharti * find receive address
38122394Sharti */
39122394Shartistruct mibrcvaddr *
40122394Shartimib_find_rcvaddr(u_int ifindex, const u_char *addr, size_t addrlen)
41122394Sharti{
42122394Sharti	struct mibrcvaddr *rcv;
43122394Sharti
44122394Sharti	TAILQ_FOREACH(rcv, &mibrcvaddr_list, link)
45122394Sharti		if (rcv->ifindex == ifindex &&
46122394Sharti		    rcv->addrlen == addrlen &&
47122394Sharti		    memcmp(rcv->addr, addr, addrlen) == 0)
48122394Sharti			return (rcv);
49122394Sharti	return (NULL);
50122394Sharti}
51122394Sharti
52122394Sharti/*
53122394Sharti * Create receive address
54122394Sharti */
55122394Shartistruct mibrcvaddr *
56122394Shartimib_rcvaddr_create(struct mibif *ifp, const u_char *addr, size_t addrlen)
57122394Sharti{
58122394Sharti	struct mibrcvaddr *rcv;
59122394Sharti	u_int i;
60122394Sharti
61122394Sharti	if (addrlen + OIDLEN_ifRcvAddressEntry + 1 > ASN_MAXOIDLEN)
62122394Sharti		return (NULL);
63122394Sharti
64122394Sharti	if ((rcv = malloc(sizeof(*rcv))) == NULL)
65122394Sharti		return (NULL);
66122394Sharti	rcv->ifindex = ifp->index;
67122394Sharti	rcv->addrlen = addrlen;
68122394Sharti	memcpy(rcv->addr, addr, addrlen);
69122394Sharti	rcv->flags = 0;
70122394Sharti
71122394Sharti	rcv->index.len = addrlen + 2;
72122394Sharti	rcv->index.subs[0] = ifp->index;
73122394Sharti	rcv->index.subs[1] = addrlen;
74122394Sharti	for (i = 0; i < addrlen; i++)
75122394Sharti		rcv->index.subs[i + 2] = addr[i];
76122394Sharti
77122394Sharti	INSERT_OBJECT_OID(rcv, &mibrcvaddr_list);
78122394Sharti
79122394Sharti	return (rcv);
80122394Sharti}
81122394Sharti
82122394Sharti/*
83122394Sharti * Delete a receive address
84122394Sharti */
85122394Shartivoid
86122394Shartimib_rcvaddr_delete(struct mibrcvaddr *rcv)
87122394Sharti{
88122394Sharti	TAILQ_REMOVE(&mibrcvaddr_list, rcv, link);
89122394Sharti	free(rcv);
90122394Sharti}
91122394Sharti
92122394Shartiint
93122394Shartiop_rcvaddr(struct snmp_context *ctx __unused, struct snmp_value *value,
94122394Sharti    u_int sub, u_int iidx __unused, enum snmp_op op)
95122394Sharti{
96122394Sharti	struct mibrcvaddr *rcv;
97122394Sharti
98122394Sharti	rcv = NULL;	/* make compiler happy */
99122394Sharti
100122394Sharti	switch (op) {
101122394Sharti
102122394Sharti	  case SNMP_OP_GETNEXT:
103122394Sharti		if ((rcv = NEXT_OBJECT_OID(&mibrcvaddr_list, &value->var, sub)) == NULL)
104122394Sharti			return (SNMP_ERR_NOSUCHNAME);
105122394Sharti		index_append(&value->var, sub, &rcv->index);
106122394Sharti		break;
107122394Sharti
108122394Sharti	  case SNMP_OP_GET:
109122394Sharti		if ((rcv = FIND_OBJECT_OID(&mibrcvaddr_list, &value->var, sub)) == NULL)
110122394Sharti			return (SNMP_ERR_NOSUCHNAME);
111122394Sharti		break;
112122394Sharti
113122394Sharti	  case SNMP_OP_SET:
114122394Sharti		if ((rcv = FIND_OBJECT_OID(&mibrcvaddr_list, &value->var, sub)) == NULL)
115122394Sharti			return (SNMP_ERR_NO_CREATION);
116122394Sharti		return (SNMP_ERR_NOT_WRITEABLE);
117122394Sharti
118122394Sharti	  case SNMP_OP_ROLLBACK:
119122394Sharti	  case SNMP_OP_COMMIT:
120122394Sharti		abort();
121122394Sharti	}
122122394Sharti
123122394Sharti	switch (value->var.subs[sub - 1]) {
124122394Sharti
125122394Sharti	  case LEAF_ifRcvAddressStatus:
126122394Sharti		value->v.integer = 1;
127122394Sharti		break;
128122394Sharti
129122394Sharti	  case LEAF_ifRcvAddressType:
130122394Sharti		value->v.integer = (rcv->flags & MIBRCVADDR_VOLATILE) ? 2 : 3;
131122394Sharti		break;
132122394Sharti	}
133122394Sharti	return (SNMP_ERR_NOERROR);
134122394Sharti}
135