~clint-fewbar/ubuntu/precise/squid3/ignore-sighup-early

« back to all changes in this revision

Viewing changes to src/snmp_core.cc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2006-11-11 10:32:06 UTC
  • Revision ID: james.westby@ubuntu.com-20061111103206-f3p0r9g0vq44rp3r
Tags: upstream-3.0.PRE5
ImportĀ upstreamĀ versionĀ 3.0.PRE5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * $Id: snmp_core.cc,v 1.75 2006/09/22 02:48:51 hno Exp $
 
4
 *
 
5
 * DEBUG: section 49    SNMP support
 
6
 * AUTHOR: Glenn Chisholm
 
7
 *
 
8
 * SQUID Web Proxy Cache          http://www.squid-cache.org/
 
9
 * ----------------------------------------------------------
 
10
 *
 
11
 *  Squid is the result of efforts by numerous individuals from
 
12
 *  the Internet community; see the CONTRIBUTORS file for full
 
13
 *  details.   Many organizations have provided support for Squid's
 
14
 *  development; see the SPONSORS file for full details.  Squid is
 
15
 *  Copyrighted (C) 2001 by the Regents of the University of
 
16
 *  California; see the COPYRIGHT file for full details.  Squid
 
17
 *  incorporates software developed and/or copyrighted by other
 
18
 *  sources; see the CREDITS file for full details.
 
19
 *
 
20
 *  This program is free software; you can redistribute it and/or modify
 
21
 *  it under the terms of the GNU General Public License as published by
 
22
 *  the Free Software Foundation; either version 2 of the License, or
 
23
 *  (at your option) any later version.
 
24
 *  
 
25
 *  This program is distributed in the hope that it will be useful,
 
26
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
27
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
28
 *  GNU General Public License for more details.
 
29
 *  
 
30
 *  You should have received a copy of the GNU General Public License
 
31
 *  along with this program; if not, write to the Free Software
 
32
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 
33
 *
 
34
 */
 
35
#include "squid.h"
 
36
#include "comm.h"
 
37
#include "cache_snmp.h"
 
38
#include "ACLChecklist.h"
 
39
 
 
40
#define SNMP_REQUEST_SIZE 4096
 
41
#define MAX_PROTOSTAT 5
 
42
 
 
43
typedef struct _mib_tree_entry mib_tree_entry;
 
44
typedef oid *(instance_Fn) (oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
 
45
 
 
46
struct _mib_tree_entry
 
47
{
 
48
    oid *name;
 
49
    int len;
 
50
    oid_ParseFn *parsefunction;
 
51
    instance_Fn *instancefunction;
 
52
    int children;
 
53
 
 
54
    struct _mib_tree_entry **leaves;
 
55
 
 
56
    struct _mib_tree_entry *parent;
 
57
};
 
58
 
 
59
mib_tree_entry *mib_tree_head;
 
60
mib_tree_entry *mib_tree_last;
 
61
 
 
62
#if STDC_HEADERS
 
63
static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...);
 
64
static oid *snmpCreateOid(int length,...);
 
65
#else
 
66
static mib_tree_entry *snmpAddNode();
 
67
static oid *snmpCreateOid();
 
68
#endif
 
69
SQUIDCEXTERN void (*snmplib_debug_hook) (int, char *);
 
70
static oid *static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
 
71
static oid *time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
 
72
static oid *peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
 
73
static oid *client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
 
74
static void snmpDecodePacket(snmp_request_t * rq);
 
75
static void snmpConstructReponse(snmp_request_t * rq);
 
76
 
 
77
static struct snmp_pdu *snmpAgentResponse(struct snmp_pdu *PDU);
 
78
static oid_ParseFn *snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen);
 
79
static oid_ParseFn *snmpTreeGet(oid * Current, snint CurrentLen);
 
80
static mib_tree_entry *snmpTreeEntry(oid entry, snint len, mib_tree_entry * current);
 
81
static mib_tree_entry *snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current);
 
82
static void snmpSnmplibDebug(int lvl, char *buf);
 
83
 
 
84
 
 
85
/*
 
86
 * The functions used during startup:
 
87
 * snmpInit
 
88
 * snmpConnectionOpen
 
89
 * snmpConnectionShutdown
 
90
 * snmpConnectionClose
 
91
 */
 
92
 
 
93
/*
 
94
 * Turns the MIB into a Tree structure. Called during the startup process.
 
95
 */
 
96
void
 
97
snmpInit(void)
 
98
{
 
99
    debug(49, 5) ("snmpInit: Called.\n");
 
100
 
 
101
    debug(49, 5) ("snmpInit: Building SNMP mib tree structure\n");
 
102
 
 
103
    snmplib_debug_hook = snmpSnmplibDebug;
 
104
 
 
105
    mib_tree_head = snmpAddNode(snmpCreateOid(1, 1),
 
106
                                1, NULL, NULL, 1,
 
107
                                snmpAddNode(snmpCreateOid(2, 1, 3),
 
108
                                            2, NULL, NULL, 1,
 
109
                                            snmpAddNode(snmpCreateOid(3, 1, 3, 6),
 
110
                                                        3, NULL, NULL, 1,
 
111
                                                        snmpAddNode(snmpCreateOid(4, 1, 3, 6, 1),
 
112
                                                                    4, NULL, NULL, 1,
 
113
                                                                    snmpAddNode(snmpCreateOid(5, 1, 3, 6, 1, 4),
 
114
                                                                                5, NULL, NULL, 1,
 
115
                                                                                snmpAddNode(snmpCreateOid(6, 1, 3, 6, 1, 4, 1),
 
116
                                                                                            6, NULL, NULL, 1,
 
117
                                                                                            snmpAddNode(snmpCreateOid(7, 1, 3, 6, 1, 4, 1, 3495),
 
118
                                                                                                        7, NULL, NULL, 1,
 
119
                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQUIDMIB, SQUIDMIB),
 
120
                                                                                                                    8, NULL, NULL, 5,
 
121
                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_SYS, SQ_SYS),
 
122
                                                                                                                                LEN_SQ_SYS, NULL, NULL, 3,
 
123
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYSVMSIZ),
 
124
                                                                                                                                            LEN_SYS, snmp_sysFn, static_Inst, 0),
 
125
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYSSTOR),
 
126
                                                                                                                                            LEN_SYS, snmp_sysFn, static_Inst, 0),
 
127
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_SYS, SYS_UPTIME),
 
128
                                                                                                                                            LEN_SYS, snmp_sysFn, static_Inst, 0)),
 
129
                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_CONF, SQ_CONF),
 
130
                                                                                                                                LEN_SQ_CONF, NULL, NULL, 6,
 
131
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_ADMIN),
 
132
                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0),
 
133
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_VERSION),
 
134
                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0),
 
135
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_VERSION_ID),
 
136
                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0),
 
137
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_LOG_FAC),
 
138
                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0),
 
139
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_STORAGE),
 
140
                                                                                                                                            LEN_SYS, NULL, NULL, 4,
 
141
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_MMAXSZ),
 
142
                                                                                                                                                        LEN_CONF_ST, snmp_confFn, static_Inst, 0),
 
143
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWMAXSZ),
 
144
                                                                                                                                                        LEN_CONF_ST, snmp_confFn, static_Inst, 0),
 
145
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWHIWM),
 
146
                                                                                                                                                        LEN_CONF_ST, snmp_confFn, static_Inst, 0),
 
147
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_CONF_ST, SQ_CONF, CONF_STORAGE, CONF_ST_SWLOWM),
 
148
                                                                                                                                                        LEN_CONF_ST, snmp_confFn, static_Inst, 0)),
 
149
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SYS, SQ_CONF, CONF_UNIQNAME),
 
150
                                                                                                                                            LEN_SYS, snmp_confFn, static_Inst, 0)),
 
151
                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF, SQ_PRF),
 
152
                                                                                                                                LEN_SQ_PRF, NULL, NULL, 2,
 
153
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_SYS),
 
154
                                                                                                                                            LEN_SQ_PRF + 1, NULL, NULL, 13,
 
155
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 1),
 
156
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
157
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 2),
 
158
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
159
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 3),
 
160
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
161
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 4),
 
162
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
163
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 5),
 
164
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
165
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 6),
 
166
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
167
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 7),
 
168
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
169
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 8),
 
170
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
171
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 9),
 
172
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
173
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 10),
 
174
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
175
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 11),
 
176
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
177
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 12),
 
178
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
 
179
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 13),
 
180
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0)),
 
181
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_PROTO),
 
182
                                                                                                                                            LEN_SQ_PRF + 1, NULL, NULL, 2,
 
183
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 1),
 
184
                                                                                                                                                        LEN_SQ_PRF + 2, NULL, NULL, 15,
 
185
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 1),
 
186
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
187
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 2),
 
188
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
189
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 3),
 
190
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
191
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 4),
 
192
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
193
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 5),
 
194
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
195
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 6),
 
196
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
197
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 7),
 
198
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
199
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 8),
 
200
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
201
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 9),
 
202
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
203
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 10),
 
204
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
205
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 11),
 
206
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
207
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 12),
 
208
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
209
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 13),
 
210
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
211
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 14),
 
212
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
 
213
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 15),
 
214
                                                                                                                                                                    LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0)),
 
215
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 2),
 
216
                                                                                                                                                        LEN_SQ_PRF + 2, NULL, NULL, 1,
 
217
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 2, 1),
 
218
                                                                                                                                                                    LEN_SQ_PRF + 3, NULL, NULL, 11,
 
219
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 1),
 
220
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
221
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 2),
 
222
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
223
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 3),
 
224
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
225
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 4),
 
226
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
227
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 5),
 
228
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
229
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 6),
 
230
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
231
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 7),
 
232
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
233
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 8),
 
234
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
235
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 9),
 
236
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
237
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 10),
 
238
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
 
239
                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 11),
 
240
                                                                                                                                                                                LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0))))),
 
241
                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_NET, SQ_NET),
 
242
                                                                                                                                LEN_SQ_NET, NULL, NULL, 3,
 
243
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_IP_CACHE),
 
244
                                                                                                                                            LEN_SQ_NET + 1, NULL, NULL, 8,
 
245
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_ENT),
 
246
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
 
247
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_REQ),
 
248
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
 
249
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_HITS),
 
250
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
 
251
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_PENDHIT),
 
252
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
 
253
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_NEGHIT),
 
254
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
 
255
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_MISS),
 
256
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
 
257
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_GHBN),
 
258
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0),
 
259
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_IP_CACHE, IP_LOC),
 
260
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIpFn, static_Inst, 0)),
 
261
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_FQDN_CACHE),
 
262
                                                                                                                                            LEN_SQ_NET + 1, NULL, NULL, 7,
 
263
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_ENT),
 
264
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
 
265
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_REQ),
 
266
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
 
267
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_HITS),
 
268
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
 
269
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_PENDHIT),
 
270
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
 
271
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_NEGHIT),
 
272
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
 
273
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_MISS),
 
274
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0),
 
275
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_FQDN_CACHE, FQDN_GHBN),
 
276
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netFqdnFn, static_Inst, 0)),
 
277
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, NET_DNS_CACHE),
 
278
                                                                                                                                            LEN_SQ_NET + 1, NULL, NULL, 3,
 
279
#if USE_DNSSERVERS
 
280
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REQ),
 
281
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0),
 
282
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REP),
 
283
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0),
 
284
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_SERVERS),
 
285
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netDnsFn, static_Inst, 0))),
 
286
#else
 
287
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REQ),
 
288
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0),
 
289
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_REP),
 
290
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0),
 
291
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, NET_DNS_CACHE, DNS_SERVERS),
 
292
                                                                                                                                                        LEN_SQ_NET + 2, snmp_netIdnsFn, static_Inst, 0))),
 
293
#endif
 
294
                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_MESH, SQ_MESH),
 
295
                                                                                                                                LEN_SQ_MESH, NULL, NULL, 2,
 
296
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 1),
 
297
                                                                                                                                            LEN_SQ_MESH + 1, NULL, NULL, 1,
 
298
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 1, 1),
 
299
                                                                                                                                                        LEN_SQ_MESH + 2, NULL, NULL, 13,
 
300
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 1),
 
301
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
302
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 2),
 
303
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
304
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 3),
 
305
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
306
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 4),
 
307
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
308
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 5),
 
309
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
310
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 6),
 
311
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
312
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 7),
 
313
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
314
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 8),
 
315
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
316
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 9),
 
317
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
318
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 10),
 
319
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
320
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 11),
 
321
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
322
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 12),
 
323
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
 
324
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 13),
 
325
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0))),
 
326
                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 2),
 
327
                                                                                                                                            LEN_SQ_MESH + 1, NULL, NULL, 1,
 
328
                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 2, 1),
 
329
                                                                                                                                                        LEN_SQ_MESH + 2, NULL, NULL, 9,
 
330
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 1),
 
331
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
 
332
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 2),
 
333
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
 
334
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 3),
 
335
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
 
336
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 4),
 
337
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
 
338
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 5),
 
339
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
 
340
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 6),
 
341
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
 
342
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 7),
 
343
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
 
344
                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 8),
 
345
                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
 
346
                                                                                                                                                        (mib_tree_last = snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 9),
 
347
                                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0)))))
 
348
                                                                                                                   )
 
349
                                                                                                       )
 
350
                                                                                           )
 
351
                                                                               )
 
352
                                                                   )
 
353
                                                       )
 
354
                                           )
 
355
                               );
 
356
 
 
357
    debug(49, 9) ("snmpInit: Completed SNMP mib tree structure\n");
 
358
}
 
359
 
 
360
void
 
361
snmpConnectionOpen(void)
 
362
{
 
363
    u_short port;
 
364
 
 
365
    struct sockaddr_in xaddr;
 
366
    socklen_t len;
 
367
    int x;
 
368
 
 
369
    debug(49, 5) ("snmpConnectionOpen: Called\n");
 
370
 
 
371
    if ((port = Config.Port.snmp) > (u_short) 0) {
 
372
        enter_suid();
 
373
        theInSnmpConnection = comm_open(SOCK_DGRAM,
 
374
                                        IPPROTO_UDP,
 
375
                                        Config.Addrs.snmp_incoming,
 
376
                                        port,
 
377
                                        COMM_NONBLOCKING,
 
378
                                        "SNMP Port");
 
379
        leave_suid();
 
380
 
 
381
        if (theInSnmpConnection < 0)
 
382
            fatal("Cannot open snmp Port");
 
383
 
 
384
        commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
385
 
 
386
        debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n",
 
387
                     (int) port, theInSnmpConnection);
 
388
 
 
389
        if (Config.Addrs.snmp_outgoing.s_addr != no_addr.s_addr) {
 
390
            enter_suid();
 
391
            theOutSnmpConnection = comm_open(SOCK_DGRAM,
 
392
                                             IPPROTO_UDP,
 
393
                                             Config.Addrs.snmp_outgoing,
 
394
                                             port,
 
395
                                             COMM_NONBLOCKING,
 
396
                                             "SNMP Port");
 
397
            leave_suid();
 
398
 
 
399
            if (theOutSnmpConnection < 0)
 
400
                fatal("Cannot open Outgoing SNMP Port");
 
401
 
 
402
            commSetSelect(theOutSnmpConnection,
 
403
                          COMM_SELECT_READ,
 
404
                          snmpHandleUdp,
 
405
                          NULL, 0);
 
406
 
 
407
            debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n",
 
408
                         (int) port, theOutSnmpConnection);
 
409
 
 
410
            fd_note(theOutSnmpConnection, "Outgoing SNMP socket");
 
411
 
 
412
            fd_note(theInSnmpConnection, "Incoming SNMP socket");
 
413
        } else {
 
414
            theOutSnmpConnection = theInSnmpConnection;
 
415
        }
 
416
 
 
417
        memset(&theOutSNMPAddr, '\0', sizeof(struct IN_ADDR));
 
418
 
 
419
        len = sizeof(struct sockaddr_in);
 
420
        memset(&xaddr, '\0', len);
 
421
        x = getsockname(theOutSnmpConnection,
 
422
 
 
423
                        (struct sockaddr *) &xaddr, &len);
 
424
 
 
425
        if (x < 0)
 
426
            debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %s\n",
 
427
                          theOutSnmpConnection, xstrerror());
 
428
        else
 
429
            theOutSNMPAddr = xaddr.sin_addr;
 
430
    }
 
431
}
 
432
 
 
433
void
 
434
snmpConnectionShutdown(void)
 
435
{
 
436
    if (theInSnmpConnection < 0)
 
437
        return;
 
438
 
 
439
    if (theInSnmpConnection != theOutSnmpConnection) {
 
440
        debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection);
 
441
        comm_close(theInSnmpConnection);
 
442
    }
 
443
 
 
444
    /*
 
445
     * Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in'
 
446
     * and 'out' sockets might be just one FD.  This prevents this
 
447
     * function from executing repeatedly.  When we are really ready to
 
448
     * exit or restart, main will comm_close the 'out' descriptor.
 
449
     */ theInSnmpConnection = -1;
 
450
 
 
451
    /*
 
452
     * Normally we only write to the outgoing SNMP socket, but we
 
453
     * also have a read handler there to catch messages sent to that
 
454
     * specific interface.  During shutdown, we must disable reading
 
455
     * on the outgoing socket.
 
456
     */
 
457
    assert(theOutSnmpConnection > -1);
 
458
 
 
459
    commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
 
460
}
 
461
 
 
462
void
 
463
snmpConnectionClose(void)
 
464
{
 
465
    snmpConnectionShutdown();
 
466
 
 
467
    if (theOutSnmpConnection > -1) {
 
468
        debug(49, 1) ("FD %d Closing SNMP socket\n", theOutSnmpConnection);
 
469
        comm_close(theOutSnmpConnection);
 
470
    }
 
471
}
 
472
 
 
473
/*
 
474
 * Functions for handling the requests.
 
475
 */
 
476
 
 
477
/*
 
478
 * Accept the UDP packet
 
479
 */
 
480
void
 
481
snmpHandleUdp(int sock, void *not_used)
 
482
{
 
483
    LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
 
484
 
 
485
    struct sockaddr_in from;
 
486
    socklen_t from_len;
 
487
    snmp_request_t *snmp_rq;
 
488
    int len;
 
489
 
 
490
    debug(49, 5) ("snmpHandleUdp: Called.\n");
 
491
 
 
492
    commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
493
 
 
494
    from_len = sizeof(struct sockaddr_in);
 
495
    memset(&from, '\0', from_len);
 
496
    memset(buf, '\0', SNMP_REQUEST_SIZE);
 
497
 
 
498
    len = comm_udp_recvfrom(sock,
 
499
                            buf,
 
500
                            SNMP_REQUEST_SIZE,
 
501
                            0,
 
502
 
 
503
                            (struct sockaddr *) &from,
 
504
                            &from_len);
 
505
 
 
506
    if (len > 0) {
 
507
        buf[len] = '\0';
 
508
        debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
 
509
                      sock,
 
510
                      len,
 
511
                      inet_ntoa(from.sin_addr));
 
512
 
 
513
        snmp_rq = (snmp_request_t *)xcalloc(1, sizeof(snmp_request_t));
 
514
        snmp_rq->buf = (u_char *) buf;
 
515
        snmp_rq->len = len;
 
516
        snmp_rq->sock = sock;
 
517
        snmp_rq->outbuf = (unsigned char *)xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE);
 
518
 
 
519
        xmemcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in));
 
520
        snmpDecodePacket(snmp_rq);
 
521
        xfree(snmp_rq->outbuf);
 
522
        xfree(snmp_rq);
 
523
    } else {
 
524
        debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock, xstrerror());
 
525
    }
 
526
}
 
527
 
 
528
/*
 
529
 * Turn SNMP packet into a PDU, check available ACL's
 
530
 */
 
531
static void
 
532
snmpDecodePacket(snmp_request_t * rq)
 
533
{
 
534
 
 
535
    struct snmp_pdu *PDU;
 
536
 
 
537
    u_char *Community;
 
538
    u_char *buf = rq->buf;
 
539
    int len = rq->len;
 
540
    int allow = 0;
 
541
 
 
542
    debug(49, 5) ("snmpDecodePacket: Called.\n");
 
543
    /* Now that we have the data, turn it into a PDU */
 
544
    PDU = snmp_pdu_create(0);
 
545
    rq->session.Version = SNMP_VERSION_1;
 
546
    Community = snmp_parse(&rq->session, PDU, buf, len);
 
547
 
 
548
    if (Community) {
 
549
        ACLChecklist checklist;
 
550
        checklist.accessList = cbdataReference(Config.accessList.snmp);
 
551
        checklist.src_addr = rq->from.sin_addr;
 
552
        checklist.snmp_community = (char *) Community;
 
553
        /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
 
554
        allow = checklist.fastCheck();
 
555
    }
 
556
 
 
557
    if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {
 
558
        rq->community = Community;
 
559
        rq->PDU = PDU;
 
560
        debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU->reqid);
 
561
        snmpConstructReponse(rq);
 
562
    } else {
 
563
        debug(49, 1) ("Failed SNMP agent query from : %s.\n",
 
564
                      inet_ntoa(rq->from.sin_addr));
 
565
        snmp_free_pdu(PDU);
 
566
    }
 
567
 
 
568
    if (Community)
 
569
        xfree(Community);
 
570
}
 
571
 
 
572
/*
 
573
 * Packet OK, ACL Check OK, Create reponse.
 
574
 */
 
575
static void
 
576
snmpConstructReponse(snmp_request_t * rq)
 
577
{
 
578
 
 
579
    struct snmp_pdu *RespPDU;
 
580
 
 
581
    debug(49, 5) ("snmpConstructReponse: Called.\n");
 
582
    RespPDU = snmpAgentResponse(rq->PDU);
 
583
    snmp_free_pdu(rq->PDU);
 
584
 
 
585
    if (RespPDU != NULL) {
 
586
        snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen);
 
587
        comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf, rq->outlen);
 
588
        snmp_free_pdu(RespPDU);
 
589
    }
 
590
}
 
591
 
 
592
/*
 
593
 * Decide how to respond to the request, construct a response and
 
594
 * return the response to the requester.
 
595
 */
 
596
 
 
597
static struct snmp_pdu *
 
598
 
 
599
            snmpAgentResponse(struct snmp_pdu *PDU)
 
600
{
 
601
 
 
602
    struct snmp_pdu *Answer = NULL;
 
603
 
 
604
    debug(49, 5) ("snmpAgentResponse: Called.\n");
 
605
 
 
606
    if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE)))
 
607
    {
 
608
        Answer->reqid = PDU->reqid;
 
609
        Answer->errindex = 0;
 
610
 
 
611
        if (PDU->command == SNMP_PDU_GET || PDU->command == SNMP_PDU_GETNEXT) {
 
612
            int get_next = (PDU->command == SNMP_PDU_GETNEXT);
 
613
            variable_list *VarPtr_;
 
614
            variable_list **RespVars = &(Answer->variables);
 
615
            oid_ParseFn *ParseFn;
 
616
            int index = 0;
 
617
            /* Loop through all variables */
 
618
 
 
619
            for (VarPtr_ = PDU->variables; VarPtr_; VarPtr_ = VarPtr_->next_variable) {
 
620
                variable_list *VarPtr = VarPtr_;
 
621
                variable_list *VarNew = NULL;
 
622
                oid *NextOidName = NULL;
 
623
                snint NextOidNameLen = 0;
 
624
 
 
625
                index++;
 
626
 
 
627
                /* Find the parsing function for this variable */
 
628
 
 
629
                if (get_next)
 
630
                    ParseFn = snmpTreeNext(VarPtr->name, VarPtr->name_length, &NextOidName, &NextOidNameLen);
 
631
                else
 
632
                    ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length);
 
633
 
 
634
                if (ParseFn == NULL) {
 
635
                    Answer->errstat = SNMP_ERR_NOSUCHNAME;
 
636
                    debug(49, 5) ("snmpAgentResponse: No such oid. ");
 
637
                } else {
 
638
                    if (get_next) {
 
639
                        VarPtr = snmp_var_new(NextOidName, NextOidNameLen);
 
640
                        xfree(NextOidName);
 
641
                    }
 
642
 
 
643
                    int * errstatTmp =  &(Answer->errstat);
 
644
 
 
645
                    VarNew = (*ParseFn) (VarPtr, (snint *) errstatTmp);
 
646
 
 
647
                    if (get_next)
 
648
                        snmp_var_free(VarPtr);
 
649
                }
 
650
 
 
651
                /* Was there an error? */
 
652
                if ((Answer->errstat != SNMP_ERR_NOERROR) || (VarNew == NULL)) {
 
653
                    Answer->errindex = index;
 
654
                    debug(49, 5) ("snmpAgentResponse: error.\n");
 
655
 
 
656
                    if (VarNew)
 
657
                        snmp_var_free(VarNew);
 
658
 
 
659
                    /* Free the already processed results, if any */
 
660
                    while ((VarPtr = Answer->variables) != NULL) {
 
661
                        Answer->variables = VarPtr->next_variable;
 
662
                        snmp_var_free(VarPtr);
 
663
                    }
 
664
 
 
665
                    /* Steal the original PDU list of variables for the error response */
 
666
                    Answer->variables = PDU->variables;
 
667
 
 
668
                    PDU->variables = NULL;
 
669
 
 
670
                    return (Answer);
 
671
                }
 
672
 
 
673
                /* No error.  Insert this var at the end, and move on to the next.
 
674
                 */
 
675
                *RespVars = VarNew;
 
676
 
 
677
                RespVars = &(VarNew->next_variable);
 
678
            }
 
679
        }
 
680
    }
 
681
 
 
682
    return (Answer);
 
683
}
 
684
 
 
685
static oid_ParseFn *
 
686
snmpTreeGet(oid * Current, snint CurrentLen)
 
687
{
 
688
    oid_ParseFn *Fn = NULL;
 
689
    mib_tree_entry *mibTreeEntry = NULL;
 
690
    int count = 0;
 
691
 
 
692
    debug(49, 5) ("snmpTreeGet: Called\n");
 
693
 
 
694
    debug(49, 6) ("snmpTreeGet: Current : \n");
 
695
    snmpDebugOid(6, Current, CurrentLen);
 
696
 
 
697
    mibTreeEntry = mib_tree_head;
 
698
 
 
699
    if (Current[count] == mibTreeEntry->name[count]) {
 
700
        count++;
 
701
 
 
702
        while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
 
703
            mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
 
704
            count++;
 
705
        }
 
706
    }
 
707
 
 
708
    if (mibTreeEntry && mibTreeEntry->parsefunction)
 
709
        Fn = mibTreeEntry->parsefunction;
 
710
 
 
711
    debug(49, 5) ("snmpTreeGet: return\n");
 
712
 
 
713
    return (Fn);
 
714
}
 
715
 
 
716
static oid_ParseFn *
 
717
snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
 
718
{
 
719
    oid_ParseFn *Fn = NULL;
 
720
    mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL;
 
721
    int count = 0;
 
722
 
 
723
    debug(49, 5) ("snmpTreeNext: Called\n");
 
724
 
 
725
    debug(49, 6) ("snmpTreeNext: Current : \n");
 
726
    snmpDebugOid(6, Current, CurrentLen);
 
727
 
 
728
    mibTreeEntry = mib_tree_head;
 
729
 
 
730
    if (Current[count] == mibTreeEntry->name[count]) {
 
731
        count++;
 
732
 
 
733
        while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
 
734
            mib_tree_entry *nextmibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
 
735
 
 
736
            if (!nextmibTreeEntry)
 
737
                break;
 
738
            else
 
739
                mibTreeEntry = nextmibTreeEntry;
 
740
 
 
741
            count++;
 
742
        }
 
743
 
 
744
        debug(49, 5) ("snmpTreeNext: Recursed down to requested object\n");
 
745
    } else {
 
746
        return NULL;
 
747
    }
 
748
 
 
749
    if (mibTreeEntry == mib_tree_last)
 
750
        return (Fn);
 
751
 
 
752
    if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
 
753
        *NextLen = CurrentLen;
 
754
        *Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);
 
755
 
 
756
        if (*Next)
 
757
            return (Fn);
 
758
    }
 
759
 
 
760
    if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
 
761
        count--;
 
762
        nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);
 
763
 
 
764
        if (nextoid) {
 
765
            debug(49, 5) ("snmpTreeNext: Next OID found for sibling\n");
 
766
            mibTreeEntry = nextoid;
 
767
            count++;
 
768
        } else {
 
769
            debug(49, 5) ("snmpTreeNext: Attempting to recurse up for next object\n");
 
770
 
 
771
            while (!nextoid) {
 
772
                count--;
 
773
 
 
774
                if (mibTreeEntry->parent->parent) {
 
775
                    nextoid = mibTreeEntry->parent;
 
776
                    mibTreeEntry = snmpTreeEntry(Current[count] + 1, count, nextoid->parent);
 
777
 
 
778
                    if (!mibTreeEntry) {
 
779
                        mibTreeEntry = nextoid;
 
780
                        nextoid = NULL;
 
781
                    }
 
782
                } else {
 
783
                    nextoid = mibTreeEntry;
 
784
                    mibTreeEntry = NULL;
 
785
                }
 
786
            }
 
787
        }
 
788
    }
 
789
 
 
790
    while ((mibTreeEntry) && (!mibTreeEntry->parsefunction)) {
 
791
        mibTreeEntry = mibTreeEntry->leaves[0];
 
792
    }
 
793
 
 
794
    if (mibTreeEntry) {
 
795
        *NextLen = mibTreeEntry->len;
 
796
        *Next = (*mibTreeEntry->instancefunction) (mibTreeEntry->name, NextLen, mibTreeEntry, &Fn);
 
797
    }
 
798
 
 
799
    if (*Next)
 
800
        return (Fn);
 
801
    else
 
802
        return NULL;
 
803
}
 
804
 
 
805
static oid *
 
806
static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 
807
{
 
808
    oid *instance = NULL;
 
809
 
 
810
    if (*len <= current->len) {
 
811
        instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
 
812
        xmemcpy(instance, name, (sizeof(name) * *len));
 
813
        instance[*len] = 0;
 
814
        *len += 1;
 
815
    }
 
816
 
 
817
    *Fn = current->parsefunction;
 
818
    return (instance);
 
819
}
 
820
 
 
821
static oid *
 
822
time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 
823
{
 
824
    oid *instance = NULL;
 
825
    int identifier = 0, loop = 0;
 
826
    int index[TIME_INDEX_LEN] =
 
827
        {TIME_INDEX};
 
828
 
 
829
    if (*len <= current->len) {
 
830
        instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
 
831
        xmemcpy(instance, name, (sizeof(name) * *len));
 
832
        instance[*len] = *index;
 
833
        *len += 1;
 
834
    } else {
 
835
        identifier = name[*len - 1];
 
836
 
 
837
        while ((identifier != index[loop]) && (loop < TIME_INDEX_LEN))
 
838
            loop++;
 
839
 
 
840
        if (loop < TIME_INDEX_LEN - 1) {
 
841
            instance = (oid *)xmalloc(sizeof(name) * (*len));
 
842
            xmemcpy(instance, name, (sizeof(name) * *len));
 
843
            instance[*len - 1] = index[++loop];
 
844
        }
 
845
    }
 
846
 
 
847
    *Fn = current->parsefunction;
 
848
    return (instance);
 
849
}
 
850
 
 
851
static oid *
 
852
peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 
853
{
 
854
    oid *instance = NULL;
 
855
    u_char *cp = NULL;
 
856
    peer *peers = Config.peers;
 
857
 
 
858
    struct IN_ADDR *laddr = NULL;
 
859
    char *host_addr = NULL, *current_addr = NULL, *last_addr = NULL;
 
860
 
 
861
    if (peers == NULL) {
 
862
        current = current->parent->parent->parent->leaves[1];
 
863
 
 
864
        while ((current) && (!current->parsefunction))
 
865
            current = current->leaves[0];
 
866
 
 
867
        instance = client_Inst(current->name, len, current, Fn);
 
868
    } else if (*len <= current->len) {
 
869
        instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
 
870
        xmemcpy(instance, name, (sizeof(name) * *len));
 
871
        cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
 
872
        instance[*len] = *cp++;
 
873
        instance[*len + 1] = *cp++;
 
874
        instance[*len + 2] = *cp++;
 
875
        instance[*len + 3] = *cp++;
 
876
        *len += 4;
 
877
    } else {
 
878
        laddr = oid2addr(&name[*len - 4]);
 
879
        host_addr = inet_ntoa(*laddr);
 
880
        last_addr = (char *)xmalloc(strlen(host_addr));
 
881
        strncpy(last_addr, host_addr, strlen(host_addr));
 
882
        current_addr = inet_ntoa(peers->in_addr.sin_addr);
 
883
 
 
884
        while ((peers) && (strncmp(last_addr, current_addr, strlen(current_addr)))) {
 
885
            if (peers->next) {
 
886
                peers = peers->next;
 
887
                current_addr = inet_ntoa(peers->in_addr.sin_addr);
 
888
            } else {
 
889
                peers = NULL;
 
890
            }
 
891
        }
 
892
 
 
893
        xfree(last_addr);
 
894
 
 
895
        if (peers) {
 
896
            if (peers->next) {
 
897
                peers = peers->next;
 
898
                instance = (oid *)xmalloc(sizeof(name) * (*len));
 
899
                xmemcpy(instance, name, (sizeof(name) * *len));
 
900
                cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
 
901
                instance[*len - 4] = *cp++;
 
902
                instance[*len - 3] = *cp++;
 
903
                instance[*len - 2] = *cp++;
 
904
                instance[*len - 1] = *cp++;
 
905
            } else {
 
906
                return (instance);
 
907
            }
 
908
        } else {
 
909
            return (instance);
 
910
        }
 
911
    }
 
912
 
 
913
    *Fn = current->parsefunction;
 
914
    return (instance);
 
915
}
 
916
 
 
917
static oid *
 
918
client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 
919
{
 
920
    oid *instance = NULL;
 
921
    u_char *cp = NULL;
 
922
 
 
923
    struct IN_ADDR *laddr = NULL;
 
924
 
 
925
    if (*len <= current->len) {
 
926
        instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
 
927
        xmemcpy(instance, name, (sizeof(name) * *len));
 
928
        laddr = client_entry(NULL);
 
929
 
 
930
        if (laddr) {
 
931
            cp = (u_char *) & (laddr->s_addr);
 
932
            instance[*len] = *cp++;
 
933
            instance[*len + 1] = *cp++;
 
934
            instance[*len + 2] = *cp++;
 
935
            instance[*len + 3] = *cp++;
 
936
            *len += 4;
 
937
        }
 
938
    } else {
 
939
        laddr = oid2addr(&name[*len - 4]);
 
940
        laddr = client_entry(laddr);
 
941
 
 
942
        if (laddr) {
 
943
            instance = (oid *)xmalloc(sizeof(name) * (*len));
 
944
            xmemcpy(instance, name, (sizeof(name) * *len));
 
945
            cp = (u_char *) & (laddr->s_addr);
 
946
            instance[*len - 4] = *cp++;
 
947
            instance[*len - 3] = *cp++;
 
948
            instance[*len - 2] = *cp++;
 
949
            instance[*len - 1] = *cp++;
 
950
        }
 
951
    }
 
952
 
 
953
    *Fn = current->parsefunction;
 
954
    return (instance);
 
955
}
 
956
 
 
957
 
 
958
/*
 
959
 * Utility functions
 
960
 */
 
961
 
 
962
/*
 
963
 * Tree utility functions. 
 
964
 */
 
965
 
 
966
/*
 
967
 * Returns a the sibling object in the tree
 
968
 */
 
969
static mib_tree_entry *
 
970
snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
 
971
{
 
972
    mib_tree_entry *next = NULL;
 
973
    int count = 0;
 
974
 
 
975
    while ((!next) && (count < current->children)) {
 
976
        if (current->leaves[count]->name[len] == entry) {
 
977
            next = current->leaves[count];
 
978
        }
 
979
 
 
980
        count++;
 
981
    }
 
982
 
 
983
    if (count < current->children) {
 
984
        next = current->leaves[count];
 
985
    } else {
 
986
        next = NULL;
 
987
    }
 
988
 
 
989
    return (next);
 
990
}
 
991
 
 
992
/*
 
993
 * Returns the requested child object or NULL if it does not exist
 
994
 */
 
995
static mib_tree_entry *
 
996
snmpTreeEntry(oid entry, snint len, mib_tree_entry * current)
 
997
{
 
998
    mib_tree_entry *next = NULL;
 
999
    int count = 0;
 
1000
 
 
1001
    while ((!next) && (count < current->children)) {
 
1002
        if (current->leaves[count]->name[len] == entry) {
 
1003
            next = current->leaves[count];
 
1004
        }
 
1005
 
 
1006
        count++;
 
1007
    }
 
1008
 
 
1009
    return (next);
 
1010
}
 
1011
 
 
1012
/*
 
1013
 * Adds a node to the MIB tree structure and adds the appropriate children
 
1014
 */
 
1015
static mib_tree_entry *
 
1016
#if STDC_HEADERS
 
1017
snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...)
 
1018
#else
 
1019
snmpAddNode(va_alist)
 
1020
va_dcl
 
1021
#endif
 
1022
{
 
1023
#if STDC_HEADERS
 
1024
    va_list args;
 
1025
    int loop;
 
1026
    mib_tree_entry *entry = NULL;
 
1027
    va_start(args, children);
 
1028
#else
 
1029
 
 
1030
    va_list args;
 
1031
    oid *name = NULL;
 
1032
    int len = 0, children = 0, loop;
 
1033
    oid_ParseFn *parsefunction = NULL;
 
1034
    instance_Fn *instancefunction = NULL;
 
1035
    mib_tree_entry *entry = NULL;
 
1036
    va_start(args);
 
1037
    name = va_arg(args, oid *);
 
1038
    len = va_arg(args, int);
 
1039
    parsefunction = va_arg(args, oid_ParseFn *);
 
1040
    instancefunction = va_arg(args, instance_Fn *);
 
1041
    children = va_arg(args, int);
 
1042
#endif
 
1043
 
 
1044
    debug(49, 6) ("snmpAddNode: Children : %d, Oid : \n", children);
 
1045
    snmpDebugOid(6, name, len);
 
1046
 
 
1047
    va_start(args, children);
 
1048
    entry = (mib_tree_entry *)xmalloc(sizeof(mib_tree_entry));
 
1049
    entry->name = name;
 
1050
    entry->len = len;
 
1051
    entry->parsefunction = parsefunction;
 
1052
    entry->instancefunction = instancefunction;
 
1053
    entry->children = children;
 
1054
 
 
1055
    if (children > 0)
 
1056
    {
 
1057
        entry->leaves = (mib_tree_entry **)xmalloc(sizeof(mib_tree_entry *) * children);
 
1058
 
 
1059
        for (loop = 0; loop < children; loop++) {
 
1060
            entry->leaves[loop] = va_arg(args, mib_tree_entry *);
 
1061
            entry->leaves[loop]->parent = entry;
 
1062
        }
 
1063
    }
 
1064
 
 
1065
    return (entry);
 
1066
}
 
1067
/* End of tree utility functions */
 
1068
 
 
1069
/*
 
1070
 * Returns the list of parameters in an oid
 
1071
 */
 
1072
static oid *
 
1073
#if STDC_HEADERS
 
1074
snmpCreateOid(int length,...)
 
1075
#else
 
1076
snmpCreateOid(va_alist)
 
1077
va_dcl
 
1078
#endif
 
1079
{
 
1080
#if STDC_HEADERS
 
1081
    va_list args;
 
1082
    oid *new_oid;
 
1083
    int loop;
 
1084
    va_start(args, length);
 
1085
#else
 
1086
 
 
1087
    va_list args;
 
1088
    int length = 0, loop;
 
1089
    oid *new_oid;
 
1090
    va_start(args);
 
1091
    length va_arg(args, int);
 
1092
#endif
 
1093
 
 
1094
    new_oid = (oid *)xmalloc(sizeof(oid) * length);
 
1095
 
 
1096
    if (length > 0)
 
1097
    {
 
1098
        for (loop = 0; loop < length; loop++) {
 
1099
            new_oid[loop] = va_arg(args, int);
 
1100
        }
 
1101
    }
 
1102
 
 
1103
    return (new_oid);
 
1104
}
 
1105
 
 
1106
#if UNUSED_CODE
 
1107
/*
 
1108
 * Allocate space for, and copy, an OID.  Returns new oid.
 
1109
 */
 
1110
static oid *
 
1111
snmpOidDup(oid * A, snint ALen)
 
1112
{
 
1113
    oid *Ans = xmalloc(sizeof(oid) * ALen);
 
1114
    xmemcpy(Ans, A, (sizeof(oid) * ALen));
 
1115
    return Ans;
 
1116
}
 
1117
 
 
1118
#endif
 
1119
 
 
1120
/*
 
1121
 * Debug calls, prints out the OID for debugging purposes.
 
1122
 */
 
1123
void
 
1124
snmpDebugOid(int lvl, oid * Name, snint Len)
 
1125
{
 
1126
    char mbuf[16], objid[1024];
 
1127
    int x;
 
1128
    objid[0] = '\0';
 
1129
 
 
1130
    for (x = 0; x < Len; x++) {
 
1131
        snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]);
 
1132
        strncat(objid, mbuf, sizeof(objid));
 
1133
    }
 
1134
 
 
1135
    debug(49, lvl) ("   oid = %s\n", objid);
 
1136
}
 
1137
 
 
1138
static void
 
1139
snmpSnmplibDebug(int lvl, char *buf)
 
1140
{
 
1141
    debug(49, lvl) ("%s", buf);
 
1142
}
 
1143
 
 
1144
void
 
1145
 
 
1146
addr2oid(struct IN_ADDR addr, oid * Dest)
 
1147
{
 
1148
    u_char *cp;
 
1149
    cp = (u_char *) & (addr.s_addr);
 
1150
    Dest[0] = *cp++;
 
1151
    Dest[1] = *cp++;
 
1152
    Dest[2] = *cp++;
 
1153
    Dest[3] = *cp++;
 
1154
}
 
1155
 
 
1156
struct IN_ADDR
 
1157
            *
 
1158
            oid2addr(oid * id)
 
1159
{
 
1160
 
 
1161
    static struct IN_ADDR laddr;
 
1162
    u_char *cp = (u_char *) & (laddr.s_addr);
 
1163
    cp[0] = id[0];
 
1164
    cp[1] = id[1];
 
1165
    cp[2] = id[2];
 
1166
    cp[3] = id[3];
 
1167
    return &laddr;
 
1168
}
 
1169
 
 
1170
/* SNMP checklists */
 
1171
#include "ACLStrategy.h"
 
1172
#include "ACLStrategised.h"
 
1173
#include "ACLStringData.h"
 
1174
 
 
1175
class ACLSNMPCommunityStrategy : public ACLStrategy<char const *>
 
1176
{
 
1177
 
 
1178
public:
 
1179
    virtual int match (ACLData<MatchType> * &, ACLChecklist *);
 
1180
    static ACLSNMPCommunityStrategy *Instance();
 
1181
    /* Not implemented to prevent copies of the instance. */
 
1182
    /* Not private to prevent brain dead g+++ warnings about
 
1183
     * private constructors with no friends */
 
1184
    ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy const &);
 
1185
 
 
1186
private:
 
1187
    static ACLSNMPCommunityStrategy Instance_;
 
1188
    ACLSNMPCommunityStrategy(){}
 
1189
 
 
1190
    ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &);
 
1191
};
 
1192
 
 
1193
class ACLSNMPCommunity
 
1194
{
 
1195
 
 
1196
private:
 
1197
    static ACL::Prototype RegistryProtoype;
 
1198
    static ACLStrategised<char const *> RegistryEntry_;
 
1199
};
 
1200
 
 
1201
ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_, "snmp_community");
 
1202
ACLStrategised<char const *> ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community");
 
1203
 
 
1204
int
 
1205
ACLSNMPCommunityStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
 
1206
{
 
1207
    return data->match (checklist->snmp_community);
 
1208
}
 
1209
 
 
1210
ACLSNMPCommunityStrategy *
 
1211
ACLSNMPCommunityStrategy::Instance()
 
1212
{
 
1213
    return &Instance_;
 
1214
}
 
1215
 
 
1216
ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_;