mibII_ip.c revision 225736
1241519Sattilio/* 2241519Sattilio * Copyright (c) 2001-2003 3241519Sattilio * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4241519Sattilio * All rights reserved. 5241519Sattilio * 6241519Sattilio * Author: Harti Brandt <harti@freebsd.org> 7241519Sattilio * 8241519Sattilio * Redistribution and use in source and binary forms, with or without 9241519Sattilio * modification, are permitted provided that the following conditions 10241519Sattilio * are met: 11241519Sattilio * 1. Redistributions of source code must retain the above copyright 12241519Sattilio * notice, this list of conditions and the following disclaimer. 13241519Sattilio * 2. Redistributions in binary form must reproduce the above copyright 14241519Sattilio * notice, this list of conditions and the following disclaimer in the 15241519Sattilio * documentation and/or other materials provided with the distribution. 16241519Sattilio * 17241519Sattilio * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18241519Sattilio * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19241519Sattilio * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20241519Sattilio * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 21241519Sattilio * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22241519Sattilio * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23241519Sattilio * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24241519Sattilio * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25241519Sattilio * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26241519Sattilio * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27241519Sattilio * SUCH DAMAGE. 28241519Sattilio * 29241519Sattilio * $Begemot: bsnmp/snmp_mibII/mibII_ip.c,v 1.11 2005/05/23 09:03:40 brandt_h Exp $ 30241519Sattilio * 31241519Sattilio * ip group scalars. 32241519Sattilio */ 33241519Sattilio#include "mibII.h" 34241519Sattilio#include "mibII_oid.h" 35241519Sattilio#include <netinet/in_systm.h> 36241519Sattilio#include <netinet/ip.h> 37241519Sattilio#include <netinet/ip_var.h> 38241519Sattilio#include <netinet/ip_icmp.h> 39241519Sattilio#include <netinet/icmp_var.h> 40241519Sattilio 41241519Sattiliostatic struct ipstat ipstat; 42241519Sattiliostatic u_int ip_idrop; 43241519Sattiliostatic struct icmpstat icmpstat; 44241519Sattilio 45241519Sattiliostatic int ip_forwarding; 46241519Sattiliostatic int ip_defttl; 47241519Sattiliostatic uint64_t ip_tick; 48241519Sattilio 49241519Sattiliostatic uint64_t ipstat_tick; 50241519Sattilio 51241519Sattiliostatic int 52241519Sattiliofetch_ipstat(void) 53241519Sattilio{ 54241519Sattilio size_t len; 55241519Sattilio 56241519Sattilio len = sizeof(ipstat); 57241519Sattilio if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, NULL, 0) == -1) { 58241519Sattilio syslog(LOG_ERR, "net.inet.ip.stats: %m"); 59241519Sattilio return (-1); 60241519Sattilio } 61241519Sattilio if (len != sizeof(ipstat)) { 62241519Sattilio syslog(LOG_ERR, "net.inet.ip.stats: wrong size"); 63241519Sattilio return (-1); 64241519Sattilio } 65241519Sattilio len = sizeof(ip_idrop); 66241519Sattilio if (sysctlbyname("net.inet.ip.intr_queue_drops", &ip_idrop, &len, NULL, 0) == -1) 67241519Sattilio syslog(LOG_WARNING, "net.inet.ip.intr_queue_drops: %m"); 68241519Sattilio if (len != sizeof(ip_idrop)) { 69241519Sattilio syslog(LOG_WARNING, "net.inet.ip.intr_queue_drops: wrong size"); 70241519Sattilio ip_idrop = 0; 71241519Sattilio } 72241519Sattilio len = sizeof(icmpstat); 73241519Sattilio if (sysctlbyname("net.inet.icmp.stats", &icmpstat, &len, NULL, 0) == -1) { 74241519Sattilio syslog(LOG_ERR, "net.inet.icmp.stats: %m"); 75241519Sattilio return (-1); 76241519Sattilio } 77241519Sattilio if (len != sizeof(icmpstat)) { 78241519Sattilio syslog(LOG_ERR, "net.inet.icmp.stats: wrong size"); 79241519Sattilio return (-1); 80241526Sjoel } 81241519Sattilio 82241519Sattilio ipstat_tick = get_ticks(); 83241519Sattilio return (0); 84241519Sattilio} 85241519Sattilio 86241519Sattiliostatic int 87241519Sattiliofetch_ip(void) 88241519Sattilio{ 89241519Sattilio size_t len; 90241519Sattilio 91241519Sattilio len = sizeof(ip_forwarding); 92241519Sattilio if (sysctlbyname("net.inet.ip.forwarding", &ip_forwarding, &len, 93241519Sattilio NULL, 0) == -1) { 94241519Sattilio syslog(LOG_ERR, "net.inet.ip.forwarding: %m"); 95241519Sattilio return (-1); 96241519Sattilio } 97241519Sattilio if (len != sizeof(ip_forwarding)) { 98241519Sattilio syslog(LOG_ERR, "net.inet.ip.forwarding: wrong size"); 99241519Sattilio return (-1); 100241519Sattilio } 101241519Sattilio 102241519Sattilio len = sizeof(ip_defttl); 103241519Sattilio if (sysctlbyname("net.inet.ip.ttl", &ip_defttl, &len, 104241519Sattilio NULL, 0) == -1) { 105241519Sattilio syslog(LOG_ERR, "net.inet.ip.ttl: %m"); 106241519Sattilio return (-1); 107241519Sattilio } 108241519Sattilio if (len != sizeof(ip_defttl)) { 109241519Sattilio syslog(LOG_ERR, "net.inet.ip.ttl: wrong size"); 110241519Sattilio return (-1); 111241519Sattilio } 112241519Sattilio 113241519Sattilio ip_tick = get_ticks(); 114241519Sattilio return (0); 115241519Sattilio} 116241519Sattilio 117241519Sattiliostatic int 118241519Sattilioip_forward(int forw, int *old) 119241519Sattilio{ 120241519Sattilio size_t olen; 121241519Sattilio 122241519Sattilio olen = sizeof(*old); 123241519Sattilio if (sysctlbyname("net.inet.ip.forwarding", old, old ? &olen : NULL, 124241519Sattilio &forw, sizeof(forw)) == -1) { 125241519Sattilio syslog(LOG_ERR, "set net.inet.ip.forwarding: %m"); 126241519Sattilio return (-1); 127241519Sattilio } 128241519Sattilio ip_forwarding = forw; 129241519Sattilio return (0); 130241519Sattilio} 131241519Sattilio 132241519Sattiliostatic int 133241519Sattilioip_setttl(int ttl, int *old) 134241519Sattilio{ 135241519Sattilio size_t olen; 136241519Sattilio 137241519Sattilio olen = sizeof(*old); 138241527Sjoel if (sysctlbyname("net.inet.ip.ttl", old, old ? &olen : NULL, 139241519Sattilio &ttl, sizeof(ttl)) == -1) { 140241519Sattilio syslog(LOG_ERR, "set net.inet.ip.ttl: %m"); 141241519Sattilio return (-1); 142241519Sattilio } 143241519Sattilio ip_defttl = ttl; 144241527Sjoel return (0); 145241519Sattilio} 146241519Sattilio 147241519Sattilio/* 148241527Sjoel * READ/WRITE ip group. 149241519Sattilio */ 150241526Sjoelint 151241519Sattilioop_ip(struct snmp_context *ctx, struct snmp_value *value, 152241519Sattilio u_int sub, u_int idx __unused, enum snmp_op op) 153241519Sattilio{ 154241519Sattilio int old; 155241519Sattilio 156241519Sattilio switch (op) { 157241519Sattilio 158241519Sattilio case SNMP_OP_GETNEXT: 159241519Sattilio abort(); 160241519Sattilio 161241527Sjoel case SNMP_OP_GET: 162241519Sattilio break; 163241519Sattilio 164241519Sattilio case SNMP_OP_SET: 165241519Sattilio if (ip_tick < this_tick) 166241519Sattilio if (fetch_ip() == -1) 167241519Sattilio return (SNMP_ERR_GENERR); 168241519Sattilio 169241519Sattilio switch (value->var.subs[sub - 1]) { 170241519Sattilio 171241519Sattilio case LEAF_ipForwarding: 172241519Sattilio ctx->scratch->int1 = ip_forwarding ? 1 : 2; 173241526Sjoel ctx->scratch->int2 = value->v.integer; 174241519Sattilio if (value->v.integer == 1) { 175241519Sattilio if (!ip_forwarding && ip_forward(1, &old)) 176241519Sattilio return (SNMP_ERR_GENERR); 177241519Sattilio ctx->scratch->int1 = old ? 1 : 2; 178241519Sattilio } else if (value->v.integer == 2) { 179241519Sattilio if (ip_forwarding && ip_forward(0, &old)) 180241519Sattilio return (SNMP_ERR_GENERR); 181241519Sattilio ctx->scratch->int1 = old; 182241519Sattilio } else 183241519Sattilio return (SNMP_ERR_WRONG_VALUE); 184241519Sattilio break; 185241519Sattilio 186241519Sattilio case LEAF_ipDefaultTTL: 187241519Sattilio ctx->scratch->int1 = ip_defttl; 188241519Sattilio ctx->scratch->int2 = value->v.integer; 189241519Sattilio if (value->v.integer < 1 || value->v.integer > 255) 190241519Sattilio return (SNMP_ERR_WRONG_VALUE); 191241519Sattilio if (ip_defttl != value->v.integer && 192241519Sattilio ip_setttl(value->v.integer, &old)) 193241519Sattilio return (SNMP_ERR_GENERR); 194241519Sattilio ctx->scratch->int1 = old; 195241519Sattilio break; 196241519Sattilio } 197241519Sattilio return (SNMP_ERR_NOERROR); 198241519Sattilio 199241519Sattilio case SNMP_OP_ROLLBACK: 200241519Sattilio switch (value->var.subs[sub - 1]) { 201241519Sattilio 202241519Sattilio case LEAF_ipForwarding: 203241519Sattilio if (ctx->scratch->int1 == 1) { 204241519Sattilio if (ctx->scratch->int2 == 2) 205241519Sattilio (void)ip_forward(1, NULL); 206241519Sattilio } else { 207241519Sattilio if (ctx->scratch->int2 == 1) 208241519Sattilio (void)ip_forward(0, NULL); 209241519Sattilio } 210241519Sattilio break; 211241519Sattilio 212241519Sattilio case LEAF_ipDefaultTTL: 213241519Sattilio if (ctx->scratch->int1 != ctx->scratch->int2) 214241519Sattilio (void)ip_setttl(ctx->scratch->int1, NULL); 215241519Sattilio break; 216241519Sattilio } 217241519Sattilio return (SNMP_ERR_NOERROR); 218241519Sattilio 219241519Sattilio case SNMP_OP_COMMIT: 220241519Sattilio return (SNMP_ERR_NOERROR); 221241519Sattilio } 222241519Sattilio 223241519Sattilio if (ip_tick < this_tick) 224241519Sattilio if (fetch_ip() == -1) 225241519Sattilio return (SNMP_ERR_GENERR); 226241519Sattilio 227241519Sattilio switch (value->var.subs[sub - 1]) { 228241519Sattilio 229241519Sattilio case LEAF_ipForwarding: 230241519Sattilio value->v.integer = ip_forwarding ? 1 : 2; 231241519Sattilio break; 232241519Sattilio 233241519Sattilio case LEAF_ipDefaultTTL: 234241519Sattilio value->v.integer = ip_defttl; 235241519Sattilio break; 236241519Sattilio } 237241519Sattilio return (SNMP_ERR_NOERROR); 238241519Sattilio} 239241519Sattilio 240241519Sattilio/* 241241519Sattilio * READ-ONLY statistics ip group. 242241519Sattilio */ 243241527Sjoelint 244241519Sattilioop_ipstat(struct snmp_context *ctx __unused, struct snmp_value *value, 245241519Sattilio u_int sub, u_int idx __unused, enum snmp_op op) 246241519Sattilio{ 247241519Sattilio switch (op) { 248241519Sattilio 249241519Sattilio case SNMP_OP_GETNEXT: 250241519Sattilio abort(); 251241519Sattilio 252241519Sattilio case SNMP_OP_GET: 253241519Sattilio break; 254241519Sattilio 255241519Sattilio case SNMP_OP_SET: 256241519Sattilio return (SNMP_ERR_NOT_WRITEABLE); 257241519Sattilio 258241519Sattilio case SNMP_OP_ROLLBACK: 259241519Sattilio case SNMP_OP_COMMIT: 260241519Sattilio abort(); 261241519Sattilio } 262241519Sattilio 263241519Sattilio if (ipstat_tick < this_tick) 264241519Sattilio fetch_ipstat(); 265241519Sattilio 266241519Sattilio switch (value->var.subs[sub - 1]) { 267241519Sattilio 268241519Sattilio case LEAF_ipInReceives: 269241519Sattilio value->v.uint32 = ipstat.ips_total; 270241519Sattilio break; 271241519Sattilio 272241519Sattilio case LEAF_ipInHdrErrors: 273241519Sattilio value->v.uint32 = ipstat.ips_badsum + ipstat.ips_tooshort 274241519Sattilio + ipstat.ips_toosmall + ipstat.ips_badhlen 275241519Sattilio + ipstat.ips_badlen + ipstat.ips_badvers + 276241519Sattilio + ipstat.ips_toolong; 277241526Sjoel break; 278241519Sattilio 279241519Sattilio case LEAF_ipInAddrErrors: 280241519Sattilio value->v.uint32 = ipstat.ips_cantforward; 281241519Sattilio break; 282241519Sattilio 283241519Sattilio case LEAF_ipForwDatagrams: 284241519Sattilio value->v.uint32 = ipstat.ips_forward; 285241519Sattilio break; 286241519Sattilio 287241519Sattilio case LEAF_ipInUnknownProtos: 288241519Sattilio value->v.uint32 = ipstat.ips_noproto; 289241526Sjoel break; 290241519Sattilio 291241519Sattilio case LEAF_ipInDiscards: 292241519Sattilio value->v.uint32 = ip_idrop; 293241519Sattilio break; 294241519Sattilio 295241519Sattilio case LEAF_ipInDelivers: 296241519Sattilio value->v.uint32 = ipstat.ips_delivered; 297241519Sattilio break; 298241519Sattilio 299241519Sattilio case LEAF_ipOutRequests: 300241519Sattilio value->v.uint32 = ipstat.ips_localout; 301241519Sattilio break; 302241519Sattilio 303241519Sattilio case LEAF_ipOutDiscards: 304241519Sattilio value->v.uint32 = ipstat.ips_odropped; 305241519Sattilio break; 306241519Sattilio 307241519Sattilio case LEAF_ipOutNoRoutes: 308241519Sattilio value->v.uint32 = ipstat.ips_noroute; 309241519Sattilio break; 310241519Sattilio 311241519Sattilio case LEAF_ipReasmTimeout: 312241519Sattilio value->v.integer = IPFRAGTTL; 313241519Sattilio break; 314241519Sattilio 315241519Sattilio case LEAF_ipReasmReqds: 316241519Sattilio value->v.uint32 = ipstat.ips_fragments; 317241519Sattilio break; 318241519Sattilio 319241527Sjoel case LEAF_ipReasmOKs: 320241527Sjoel value->v.uint32 = ipstat.ips_reassembled; 321241519Sattilio break; 322241519Sattilio 323241519Sattilio case LEAF_ipReasmFails: 324241519Sattilio value->v.uint32 = ipstat.ips_fragdropped 325241519Sattilio + ipstat.ips_fragtimeout; 326241519Sattilio break; 327241519Sattilio 328241519Sattilio case LEAF_ipFragOKs: 329241519Sattilio value->v.uint32 = ipstat.ips_fragmented; 330241519Sattilio break; 331241519Sattilio 332241526Sjoel case LEAF_ipFragFails: 333241526Sjoel value->v.uint32 = ipstat.ips_cantfrag; 334241526Sjoel break; 335241526Sjoel 336241519Sattilio case LEAF_ipFragCreates: 337241519Sattilio value->v.uint32 = ipstat.ips_ofragments; 338241519Sattilio break; 339241519Sattilio } 340241519Sattilio return (SNMP_ERR_NOERROR); 341241519Sattilio} 342241519Sattilio 343241519Sattilio/* 344241519Sattilio * READ-ONLY statistics icmp group. 345241519Sattilio */ 346241519Sattilioint 347241519Sattilioop_icmpstat(struct snmp_context *ctx __unused, struct snmp_value *value, 348241519Sattilio u_int sub, u_int idx __unused, enum snmp_op op) 349241519Sattilio{ 350241519Sattilio u_int i; 351241526Sjoel 352241519Sattilio switch (op) { 353241519Sattilio 354241519Sattilio case SNMP_OP_GETNEXT: 355241519Sattilio abort(); 356241519Sattilio 357241519Sattilio case SNMP_OP_GET: 358241519Sattilio break; 359241519Sattilio 360241519Sattilio case SNMP_OP_SET: 361241519Sattilio return (SNMP_ERR_NOT_WRITEABLE); 362241519Sattilio 363241527Sjoel case SNMP_OP_ROLLBACK: 364 case SNMP_OP_COMMIT: 365 abort(); 366 } 367 368 if (ipstat_tick < this_tick) 369 fetch_ipstat(); 370 371 switch (value->var.subs[sub - 1]) { 372 373 case LEAF_icmpInMsgs: 374 value->v.integer = 0; 375 for (i = 0; i <= ICMP_MAXTYPE; i++) 376 value->v.integer += icmpstat.icps_inhist[i]; 377 value->v.integer += icmpstat.icps_tooshort + 378 icmpstat.icps_checksum; 379 /* missing: bad type and packets on faith */ 380 break; 381 382 case LEAF_icmpInErrors: 383 value->v.integer = icmpstat.icps_tooshort + 384 icmpstat.icps_checksum + 385 icmpstat.icps_badlen + 386 icmpstat.icps_badcode + 387 icmpstat.icps_bmcastecho + 388 icmpstat.icps_bmcasttstamp; 389 break; 390 391 case LEAF_icmpInDestUnreachs: 392 value->v.integer = icmpstat.icps_inhist[ICMP_UNREACH]; 393 break; 394 395 case LEAF_icmpInTimeExcds: 396 value->v.integer = icmpstat.icps_inhist[ICMP_TIMXCEED]; 397 break; 398 399 case LEAF_icmpInParmProbs: 400 value->v.integer = icmpstat.icps_inhist[ICMP_PARAMPROB]; 401 break; 402 403 case LEAF_icmpInSrcQuenchs: 404 value->v.integer = icmpstat.icps_inhist[ICMP_SOURCEQUENCH]; 405 break; 406 407 case LEAF_icmpInRedirects: 408 value->v.integer = icmpstat.icps_inhist[ICMP_REDIRECT]; 409 break; 410 411 case LEAF_icmpInEchos: 412 value->v.integer = icmpstat.icps_inhist[ICMP_ECHO]; 413 break; 414 415 case LEAF_icmpInEchoReps: 416 value->v.integer = icmpstat.icps_inhist[ICMP_ECHOREPLY]; 417 break; 418 419 case LEAF_icmpInTimestamps: 420 value->v.integer = icmpstat.icps_inhist[ICMP_TSTAMP]; 421 break; 422 423 case LEAF_icmpInTimestampReps: 424 value->v.integer = icmpstat.icps_inhist[ICMP_TSTAMPREPLY]; 425 break; 426 427 case LEAF_icmpInAddrMasks: 428 value->v.integer = icmpstat.icps_inhist[ICMP_MASKREQ]; 429 break; 430 431 case LEAF_icmpInAddrMaskReps: 432 value->v.integer = icmpstat.icps_inhist[ICMP_MASKREPLY]; 433 break; 434 435 case LEAF_icmpOutMsgs: 436 value->v.integer = 0; 437 for (i = 0; i <= ICMP_MAXTYPE; i++) 438 value->v.integer += icmpstat.icps_outhist[i]; 439 value->v.integer += icmpstat.icps_badaddr + 440 icmpstat.icps_noroute; 441 break; 442 443 case LEAF_icmpOutErrors: 444 value->v.integer = icmpstat.icps_badaddr + 445 icmpstat.icps_noroute; 446 break; 447 448 case LEAF_icmpOutDestUnreachs: 449 value->v.integer = icmpstat.icps_outhist[ICMP_UNREACH]; 450 break; 451 452 case LEAF_icmpOutTimeExcds: 453 value->v.integer = icmpstat.icps_outhist[ICMP_TIMXCEED]; 454 break; 455 456 case LEAF_icmpOutParmProbs: 457 value->v.integer = icmpstat.icps_outhist[ICMP_PARAMPROB]; 458 break; 459 460 case LEAF_icmpOutSrcQuenchs: 461 value->v.integer = icmpstat.icps_outhist[ICMP_SOURCEQUENCH]; 462 break; 463 464 case LEAF_icmpOutRedirects: 465 value->v.integer = icmpstat.icps_outhist[ICMP_REDIRECT]; 466 break; 467 468 case LEAF_icmpOutEchos: 469 value->v.integer = icmpstat.icps_outhist[ICMP_ECHO]; 470 break; 471 472 case LEAF_icmpOutEchoReps: 473 value->v.integer = icmpstat.icps_outhist[ICMP_ECHOREPLY]; 474 break; 475 476 case LEAF_icmpOutTimestamps: 477 value->v.integer = icmpstat.icps_outhist[ICMP_TSTAMP]; 478 break; 479 480 case LEAF_icmpOutTimestampReps: 481 value->v.integer = icmpstat.icps_outhist[ICMP_TSTAMPREPLY]; 482 break; 483 484 case LEAF_icmpOutAddrMasks: 485 value->v.integer = icmpstat.icps_outhist[ICMP_MASKREQ]; 486 break; 487 488 case LEAF_icmpOutAddrMaskReps: 489 value->v.integer = icmpstat.icps_outhist[ICMP_MASKREPLY]; 490 break; 491 } 492 return (SNMP_ERR_NOERROR); 493} 494