summaryrefslogtreecommitdiffstats
path: root/lib/snmp.c
blob: d28e6494b0261962e3e0b8bddd83774eac9ebc1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// SPDX-License-Identifier: GPL-2.0-or-later
/* SNMP support
 * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
 */

#include <zebra.h>

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

#include "smux.h"

int oid_compare(const oid *o1, int o1_len, const oid *o2, int o2_len)
{
	int i;

	for (i = 0; i < MIN(o1_len, o2_len); i++) {
		if (o1[i] < o2[i])
			return -1;
		else if (o1[i] > o2[i])
			return 1;
	}
	if (o1_len < o2_len)
		return -1;
	if (o1_len > o2_len)
		return 1;

	return 0;
}

void *oid_copy(void *dest, const void *src, size_t size)
{
	return memcpy(dest, src, size * sizeof(oid));
}

void oid2in_addr(oid oid[], int len, struct in_addr *addr)
{
	int i;
	uint8_t *pnt;

	if (len == 0)
		return;

	pnt = (uint8_t *)addr;

	for (i = 0; i < len; i++)
		*pnt++ = oid[i];
}

void oid2in6_addr(oid oid[], struct in6_addr *addr)
{
	unsigned int i;
	uint8_t *pnt;

	pnt = (uint8_t *)addr;

	for (i = 0; i < sizeof(struct in6_addr); i++)
		*pnt++ = oid[i];
}

void oid2int(oid oid[], int *dest)
{
	uint8_t i;
	uint8_t *pnt;
	int network_dest;

	pnt = (uint8_t *)&network_dest;

	for (i = 0; i < sizeof(int); i++)
		*pnt++ = oid[i];
	*dest = ntohl(network_dest);
}

void oid_copy_in_addr(oid oid[], const struct in_addr *addr)
{
	int i;
	const uint8_t *pnt;
	int len = sizeof(struct in_addr);

	pnt = (uint8_t *)addr;

	for (i = 0; i < len; i++)
		oid[i] = *pnt++;
}


void oid_copy_in6_addr(oid oid[], const struct in6_addr *addr)
{
	int i;
	const uint8_t *pnt;
	int len = sizeof(struct in6_addr);

	pnt = (uint8_t *)addr;

	for (i = 0; i < len; i++)
		oid[i] = *pnt++;
}

void oid_copy_int(oid oid[], int *val)
{
	uint8_t i;
	const uint8_t *pnt;
	int network_val;

	network_val = htonl(*val);
	pnt = (uint8_t *)&network_val;

	for (i = 0; i < sizeof(int); i++)
		oid[i] = *pnt++;
}

void oid2string(oid oid[], int len, char *string)
{
	int i;
	uint8_t *pnt;

	if (len == 0)
		return;

	pnt = (uint8_t *)string;

	for (i = 0; i < len; i++)
		*pnt++ = (uint8_t)oid[i];
}

void oid_copy_str(oid oid[], const char *string, int len)
{
	int i;
	const uint8_t *pnt;

	if (len == 0)
		return;

	pnt = (uint8_t *)string;

	for (i = 0; i < len; i++)
		oid[i] = *pnt++;
}

int smux_header_generic(struct variable *v, oid *name, size_t *length,
			int exact, size_t *var_len, WriteMethod **write_method)
{
	oid fulloid[MAX_OID_LEN];
	int ret;

	oid_copy(fulloid, v->name, v->namelen);
	fulloid[v->namelen] = 0;
	/* Check against full instance. */
	ret = oid_compare(name, *length, fulloid, v->namelen + 1);

	/* Check single instance. */
	if ((exact && (ret != 0)) || (!exact && (ret >= 0)))
		return MATCH_FAILED;

	/* In case of getnext, fill in full instance. */
	memcpy(name, fulloid, (v->namelen + 1) * sizeof(oid));
	*length = v->namelen + 1;

	*write_method = 0;
	*var_len = sizeof(long); /* default to 'long' results */

	return MATCH_SUCCEEDED;
}

int smux_header_table(struct variable *v, oid *name, size_t *length, int exact,
		      size_t *var_len, WriteMethod **write_method)
{
	/* If the requested OID name is less than OID prefix we
	   handle, adjust it to our prefix. */
	if ((oid_compare(name, *length, v->name, v->namelen)) < 0) {
		if (exact)
			return MATCH_FAILED;
		oid_copy(name, v->name, v->namelen);
		*length = v->namelen;
	}

	*write_method = 0;
	*var_len = sizeof(long);

	return MATCH_SUCCEEDED;
}