Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/bsnmp/snmp_mibII/mibII_ip.c
39478 views
1
/*
2
* Copyright (c) 2001-2003
3
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4
* All rights reserved.
5
*
6
* Author: Harti Brandt <[email protected]>
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*
29
* $Begemot: bsnmp/snmp_mibII/mibII_ip.c,v 1.11 2005/05/23 09:03:40 brandt_h Exp $
30
*
31
* ip group scalars.
32
*/
33
#include "mibII.h"
34
#include "mibII_oid.h"
35
#include <netinet/in_systm.h>
36
#include <netinet/ip.h>
37
#include <netinet/ip_var.h>
38
#include <netinet/ip_icmp.h>
39
#include <netinet/icmp_var.h>
40
41
static struct ipstat ipstat;
42
static u_int ip_idrop;
43
static struct icmpstat icmpstat;
44
45
static int ip_forwarding;
46
static int ip_defttl;
47
static u_int ip_fragttl;
48
static uint64_t ip_tick;
49
50
static uint64_t ipstat_tick;
51
52
static int
53
fetch_ipstat(void)
54
{
55
size_t len;
56
57
len = sizeof(ipstat);
58
if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, NULL, 0) == -1) {
59
syslog(LOG_ERR, "net.inet.ip.stats: %m");
60
return (-1);
61
}
62
if (len != sizeof(ipstat)) {
63
syslog(LOG_ERR, "net.inet.ip.stats: wrong size");
64
return (-1);
65
}
66
len = sizeof(ip_idrop);
67
if (sysctlbyname("net.inet.ip.intr_queue_drops", &ip_idrop, &len, NULL, 0) == -1)
68
syslog(LOG_WARNING, "net.inet.ip.intr_queue_drops: %m");
69
if (len != sizeof(ip_idrop)) {
70
syslog(LOG_WARNING, "net.inet.ip.intr_queue_drops: wrong size");
71
ip_idrop = 0;
72
}
73
len = sizeof(icmpstat);
74
if (sysctlbyname("net.inet.icmp.stats", &icmpstat, &len, NULL, 0) == -1) {
75
syslog(LOG_ERR, "net.inet.icmp.stats: %m");
76
return (-1);
77
}
78
if (len != sizeof(icmpstat)) {
79
syslog(LOG_ERR, "net.inet.icmp.stats: wrong size");
80
return (-1);
81
}
82
83
len = sizeof(ip_fragttl);
84
if (sysctlbyname("net.inet.ip.fragttl", &ip_fragttl, &len,
85
NULL, 0) == -1) {
86
syslog(LOG_ERR, "net.inet.ip.fragttl: %m");
87
return (-1);
88
}
89
if (len != sizeof(ip_fragttl)) {
90
syslog(LOG_ERR, "net.inet.ip.fragttl: wrong size");
91
return (-1);
92
}
93
94
ipstat_tick = get_ticks();
95
return (0);
96
}
97
98
static int
99
fetch_ip(void)
100
{
101
size_t len;
102
103
len = sizeof(ip_forwarding);
104
if (sysctlbyname("net.inet.ip.forwarding", &ip_forwarding, &len,
105
NULL, 0) == -1) {
106
syslog(LOG_ERR, "net.inet.ip.forwarding: %m");
107
return (-1);
108
}
109
if (len != sizeof(ip_forwarding)) {
110
syslog(LOG_ERR, "net.inet.ip.forwarding: wrong size");
111
return (-1);
112
}
113
114
len = sizeof(ip_defttl);
115
if (sysctlbyname("net.inet.ip.ttl", &ip_defttl, &len,
116
NULL, 0) == -1) {
117
syslog(LOG_ERR, "net.inet.ip.ttl: %m");
118
return (-1);
119
}
120
if (len != sizeof(ip_defttl)) {
121
syslog(LOG_ERR, "net.inet.ip.ttl: wrong size");
122
return (-1);
123
}
124
125
ip_tick = get_ticks();
126
return (0);
127
}
128
129
static int
130
ip_forward(int forw, int *old)
131
{
132
size_t olen;
133
134
olen = sizeof(*old);
135
if (sysctlbyname("net.inet.ip.forwarding", old, old ? &olen : NULL,
136
&forw, sizeof(forw)) == -1) {
137
syslog(LOG_ERR, "set net.inet.ip.forwarding: %m");
138
return (-1);
139
}
140
ip_forwarding = forw;
141
return (0);
142
}
143
144
static int
145
ip_setttl(int ttl, int *old)
146
{
147
size_t olen;
148
149
olen = sizeof(*old);
150
if (sysctlbyname("net.inet.ip.ttl", old, old ? &olen : NULL,
151
&ttl, sizeof(ttl)) == -1) {
152
syslog(LOG_ERR, "set net.inet.ip.ttl: %m");
153
return (-1);
154
}
155
ip_defttl = ttl;
156
return (0);
157
}
158
159
/*
160
* READ/WRITE ip group.
161
*/
162
int
163
op_ip(struct snmp_context *ctx, struct snmp_value *value,
164
u_int sub, u_int idx __unused, enum snmp_op op)
165
{
166
int old = 0;
167
168
switch (op) {
169
170
case SNMP_OP_GETNEXT:
171
abort();
172
173
case SNMP_OP_GET:
174
break;
175
176
case SNMP_OP_SET:
177
if (ip_tick < this_tick)
178
if (fetch_ip() == -1)
179
return (SNMP_ERR_GENERR);
180
181
switch (value->var.subs[sub - 1]) {
182
183
case LEAF_ipForwarding:
184
ctx->scratch->int1 = ip_forwarding ? 1 : 2;
185
ctx->scratch->int2 = value->v.integer;
186
if (value->v.integer == 1) {
187
if (!ip_forwarding && ip_forward(1, &old))
188
return (SNMP_ERR_GENERR);
189
ctx->scratch->int1 = old ? 1 : 2;
190
} else if (value->v.integer == 2) {
191
if (ip_forwarding && ip_forward(0, &old))
192
return (SNMP_ERR_GENERR);
193
ctx->scratch->int1 = old;
194
} else
195
return (SNMP_ERR_WRONG_VALUE);
196
break;
197
198
case LEAF_ipDefaultTTL:
199
ctx->scratch->int1 = ip_defttl;
200
ctx->scratch->int2 = value->v.integer;
201
if (value->v.integer < 1 || value->v.integer > 255)
202
return (SNMP_ERR_WRONG_VALUE);
203
if (ip_defttl != value->v.integer &&
204
ip_setttl(value->v.integer, &old))
205
return (SNMP_ERR_GENERR);
206
ctx->scratch->int1 = old;
207
break;
208
}
209
return (SNMP_ERR_NOERROR);
210
211
case SNMP_OP_ROLLBACK:
212
switch (value->var.subs[sub - 1]) {
213
214
case LEAF_ipForwarding:
215
if (ctx->scratch->int1 == 1) {
216
if (ctx->scratch->int2 == 2)
217
(void)ip_forward(1, NULL);
218
} else {
219
if (ctx->scratch->int2 == 1)
220
(void)ip_forward(0, NULL);
221
}
222
break;
223
224
case LEAF_ipDefaultTTL:
225
if (ctx->scratch->int1 != ctx->scratch->int2)
226
(void)ip_setttl(ctx->scratch->int1, NULL);
227
break;
228
}
229
return (SNMP_ERR_NOERROR);
230
231
case SNMP_OP_COMMIT:
232
return (SNMP_ERR_NOERROR);
233
}
234
235
if (ip_tick < this_tick)
236
if (fetch_ip() == -1)
237
return (SNMP_ERR_GENERR);
238
239
switch (value->var.subs[sub - 1]) {
240
241
case LEAF_ipForwarding:
242
value->v.integer = ip_forwarding ? 1 : 2;
243
break;
244
245
case LEAF_ipDefaultTTL:
246
value->v.integer = ip_defttl;
247
break;
248
}
249
return (SNMP_ERR_NOERROR);
250
}
251
252
/*
253
* READ-ONLY statistics ip group.
254
*/
255
int
256
op_ipstat(struct snmp_context *ctx __unused, struct snmp_value *value,
257
u_int sub, u_int idx __unused, enum snmp_op op)
258
{
259
switch (op) {
260
261
case SNMP_OP_GETNEXT:
262
abort();
263
264
case SNMP_OP_GET:
265
break;
266
267
case SNMP_OP_SET:
268
return (SNMP_ERR_NOT_WRITEABLE);
269
270
case SNMP_OP_ROLLBACK:
271
case SNMP_OP_COMMIT:
272
abort();
273
}
274
275
if (ipstat_tick < this_tick)
276
fetch_ipstat();
277
278
switch (value->var.subs[sub - 1]) {
279
280
case LEAF_ipInReceives:
281
value->v.uint32 = ipstat.ips_total;
282
break;
283
284
case LEAF_ipInHdrErrors:
285
value->v.uint32 = ipstat.ips_badsum + ipstat.ips_tooshort
286
+ ipstat.ips_toosmall + ipstat.ips_badhlen
287
+ ipstat.ips_badlen + ipstat.ips_badvers +
288
+ ipstat.ips_toolong;
289
break;
290
291
case LEAF_ipInAddrErrors:
292
value->v.uint32 = ipstat.ips_cantforward;
293
break;
294
295
case LEAF_ipForwDatagrams:
296
value->v.uint32 = ipstat.ips_forward;
297
break;
298
299
case LEAF_ipInUnknownProtos:
300
value->v.uint32 = ipstat.ips_noproto;
301
break;
302
303
case LEAF_ipInDiscards:
304
value->v.uint32 = ip_idrop;
305
break;
306
307
case LEAF_ipInDelivers:
308
value->v.uint32 = ipstat.ips_delivered;
309
break;
310
311
case LEAF_ipOutRequests:
312
value->v.uint32 = ipstat.ips_localout;
313
break;
314
315
case LEAF_ipOutDiscards:
316
value->v.uint32 = ipstat.ips_odropped;
317
break;
318
319
case LEAF_ipOutNoRoutes:
320
value->v.uint32 = ipstat.ips_noroute;
321
break;
322
323
case LEAF_ipReasmTimeout:
324
value->v.integer = ip_fragttl;
325
break;
326
327
case LEAF_ipReasmReqds:
328
value->v.uint32 = ipstat.ips_fragments;
329
break;
330
331
case LEAF_ipReasmOKs:
332
value->v.uint32 = ipstat.ips_reassembled;
333
break;
334
335
case LEAF_ipReasmFails:
336
value->v.uint32 = ipstat.ips_fragdropped
337
+ ipstat.ips_fragtimeout;
338
break;
339
340
case LEAF_ipFragOKs:
341
value->v.uint32 = ipstat.ips_fragmented;
342
break;
343
344
case LEAF_ipFragFails:
345
value->v.uint32 = ipstat.ips_cantfrag;
346
break;
347
348
case LEAF_ipFragCreates:
349
value->v.uint32 = ipstat.ips_ofragments;
350
break;
351
}
352
return (SNMP_ERR_NOERROR);
353
}
354
355
/*
356
* READ-ONLY statistics icmp group.
357
*/
358
int
359
op_icmpstat(struct snmp_context *ctx __unused, struct snmp_value *value,
360
u_int sub, u_int idx __unused, enum snmp_op op)
361
{
362
u_int i;
363
364
switch (op) {
365
366
case SNMP_OP_GETNEXT:
367
abort();
368
369
case SNMP_OP_GET:
370
break;
371
372
case SNMP_OP_SET:
373
return (SNMP_ERR_NOT_WRITEABLE);
374
375
case SNMP_OP_ROLLBACK:
376
case SNMP_OP_COMMIT:
377
abort();
378
}
379
380
if (ipstat_tick < this_tick)
381
fetch_ipstat();
382
383
switch (value->var.subs[sub - 1]) {
384
385
case LEAF_icmpInMsgs:
386
value->v.integer = 0;
387
for (i = 0; i <= ICMP_MAXTYPE; i++)
388
value->v.integer += icmpstat.icps_inhist[i];
389
value->v.integer += icmpstat.icps_tooshort +
390
icmpstat.icps_checksum;
391
/* missing: bad type and packets on faith */
392
break;
393
394
case LEAF_icmpInErrors:
395
value->v.integer = icmpstat.icps_tooshort +
396
icmpstat.icps_checksum +
397
icmpstat.icps_badlen +
398
icmpstat.icps_badcode +
399
icmpstat.icps_bmcastecho +
400
icmpstat.icps_bmcasttstamp;
401
break;
402
403
case LEAF_icmpInDestUnreachs:
404
value->v.integer = icmpstat.icps_inhist[ICMP_UNREACH];
405
break;
406
407
case LEAF_icmpInTimeExcds:
408
value->v.integer = icmpstat.icps_inhist[ICMP_TIMXCEED];
409
break;
410
411
case LEAF_icmpInParmProbs:
412
value->v.integer = icmpstat.icps_inhist[ICMP_PARAMPROB];
413
break;
414
415
case LEAF_icmpInSrcQuenchs:
416
value->v.integer = icmpstat.icps_inhist[ICMP_SOURCEQUENCH];
417
break;
418
419
case LEAF_icmpInRedirects:
420
value->v.integer = icmpstat.icps_inhist[ICMP_REDIRECT];
421
break;
422
423
case LEAF_icmpInEchos:
424
value->v.integer = icmpstat.icps_inhist[ICMP_ECHO];
425
break;
426
427
case LEAF_icmpInEchoReps:
428
value->v.integer = icmpstat.icps_inhist[ICMP_ECHOREPLY];
429
break;
430
431
case LEAF_icmpInTimestamps:
432
value->v.integer = icmpstat.icps_inhist[ICMP_TSTAMP];
433
break;
434
435
case LEAF_icmpInTimestampReps:
436
value->v.integer = icmpstat.icps_inhist[ICMP_TSTAMPREPLY];
437
break;
438
439
case LEAF_icmpInAddrMasks:
440
value->v.integer = icmpstat.icps_inhist[ICMP_MASKREQ];
441
break;
442
443
case LEAF_icmpInAddrMaskReps:
444
value->v.integer = icmpstat.icps_inhist[ICMP_MASKREPLY];
445
break;
446
447
case LEAF_icmpOutMsgs:
448
value->v.integer = 0;
449
for (i = 0; i <= ICMP_MAXTYPE; i++)
450
value->v.integer += icmpstat.icps_outhist[i];
451
value->v.integer += icmpstat.icps_badaddr +
452
icmpstat.icps_noroute;
453
break;
454
455
case LEAF_icmpOutErrors:
456
value->v.integer = icmpstat.icps_badaddr +
457
icmpstat.icps_noroute;
458
break;
459
460
case LEAF_icmpOutDestUnreachs:
461
value->v.integer = icmpstat.icps_outhist[ICMP_UNREACH];
462
break;
463
464
case LEAF_icmpOutTimeExcds:
465
value->v.integer = icmpstat.icps_outhist[ICMP_TIMXCEED];
466
break;
467
468
case LEAF_icmpOutParmProbs:
469
value->v.integer = icmpstat.icps_outhist[ICMP_PARAMPROB];
470
break;
471
472
case LEAF_icmpOutSrcQuenchs:
473
value->v.integer = icmpstat.icps_outhist[ICMP_SOURCEQUENCH];
474
break;
475
476
case LEAF_icmpOutRedirects:
477
value->v.integer = icmpstat.icps_outhist[ICMP_REDIRECT];
478
break;
479
480
case LEAF_icmpOutEchos:
481
value->v.integer = icmpstat.icps_outhist[ICMP_ECHO];
482
break;
483
484
case LEAF_icmpOutEchoReps:
485
value->v.integer = icmpstat.icps_outhist[ICMP_ECHOREPLY];
486
break;
487
488
case LEAF_icmpOutTimestamps:
489
value->v.integer = icmpstat.icps_outhist[ICMP_TSTAMP];
490
break;
491
492
case LEAF_icmpOutTimestampReps:
493
value->v.integer = icmpstat.icps_outhist[ICMP_TSTAMPREPLY];
494
break;
495
496
case LEAF_icmpOutAddrMasks:
497
value->v.integer = icmpstat.icps_outhist[ICMP_MASKREQ];
498
break;
499
500
case LEAF_icmpOutAddrMaskReps:
501
value->v.integer = icmpstat.icps_outhist[ICMP_MASKREPLY];
502
break;
503
}
504
return (SNMP_ERR_NOERROR);
505
}
506
507