Path: blob/main/contrib/bsnmp/snmp_mibII/mibII_ip.c
39478 views
/*1* Copyright (c) 2001-20032* Fraunhofer Institute for Open Communication Systems (FhG Fokus).3* All rights reserved.4*5* Author: Harti Brandt <[email protected]>6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*28* $Begemot: bsnmp/snmp_mibII/mibII_ip.c,v 1.11 2005/05/23 09:03:40 brandt_h Exp $29*30* ip group scalars.31*/32#include "mibII.h"33#include "mibII_oid.h"34#include <netinet/in_systm.h>35#include <netinet/ip.h>36#include <netinet/ip_var.h>37#include <netinet/ip_icmp.h>38#include <netinet/icmp_var.h>3940static struct ipstat ipstat;41static u_int ip_idrop;42static struct icmpstat icmpstat;4344static int ip_forwarding;45static int ip_defttl;46static u_int ip_fragttl;47static uint64_t ip_tick;4849static uint64_t ipstat_tick;5051static int52fetch_ipstat(void)53{54size_t len;5556len = sizeof(ipstat);57if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, NULL, 0) == -1) {58syslog(LOG_ERR, "net.inet.ip.stats: %m");59return (-1);60}61if (len != sizeof(ipstat)) {62syslog(LOG_ERR, "net.inet.ip.stats: wrong size");63return (-1);64}65len = sizeof(ip_idrop);66if (sysctlbyname("net.inet.ip.intr_queue_drops", &ip_idrop, &len, NULL, 0) == -1)67syslog(LOG_WARNING, "net.inet.ip.intr_queue_drops: %m");68if (len != sizeof(ip_idrop)) {69syslog(LOG_WARNING, "net.inet.ip.intr_queue_drops: wrong size");70ip_idrop = 0;71}72len = sizeof(icmpstat);73if (sysctlbyname("net.inet.icmp.stats", &icmpstat, &len, NULL, 0) == -1) {74syslog(LOG_ERR, "net.inet.icmp.stats: %m");75return (-1);76}77if (len != sizeof(icmpstat)) {78syslog(LOG_ERR, "net.inet.icmp.stats: wrong size");79return (-1);80}8182len = sizeof(ip_fragttl);83if (sysctlbyname("net.inet.ip.fragttl", &ip_fragttl, &len,84NULL, 0) == -1) {85syslog(LOG_ERR, "net.inet.ip.fragttl: %m");86return (-1);87}88if (len != sizeof(ip_fragttl)) {89syslog(LOG_ERR, "net.inet.ip.fragttl: wrong size");90return (-1);91}9293ipstat_tick = get_ticks();94return (0);95}9697static int98fetch_ip(void)99{100size_t len;101102len = sizeof(ip_forwarding);103if (sysctlbyname("net.inet.ip.forwarding", &ip_forwarding, &len,104NULL, 0) == -1) {105syslog(LOG_ERR, "net.inet.ip.forwarding: %m");106return (-1);107}108if (len != sizeof(ip_forwarding)) {109syslog(LOG_ERR, "net.inet.ip.forwarding: wrong size");110return (-1);111}112113len = sizeof(ip_defttl);114if (sysctlbyname("net.inet.ip.ttl", &ip_defttl, &len,115NULL, 0) == -1) {116syslog(LOG_ERR, "net.inet.ip.ttl: %m");117return (-1);118}119if (len != sizeof(ip_defttl)) {120syslog(LOG_ERR, "net.inet.ip.ttl: wrong size");121return (-1);122}123124ip_tick = get_ticks();125return (0);126}127128static int129ip_forward(int forw, int *old)130{131size_t olen;132133olen = sizeof(*old);134if (sysctlbyname("net.inet.ip.forwarding", old, old ? &olen : NULL,135&forw, sizeof(forw)) == -1) {136syslog(LOG_ERR, "set net.inet.ip.forwarding: %m");137return (-1);138}139ip_forwarding = forw;140return (0);141}142143static int144ip_setttl(int ttl, int *old)145{146size_t olen;147148olen = sizeof(*old);149if (sysctlbyname("net.inet.ip.ttl", old, old ? &olen : NULL,150&ttl, sizeof(ttl)) == -1) {151syslog(LOG_ERR, "set net.inet.ip.ttl: %m");152return (-1);153}154ip_defttl = ttl;155return (0);156}157158/*159* READ/WRITE ip group.160*/161int162op_ip(struct snmp_context *ctx, struct snmp_value *value,163u_int sub, u_int idx __unused, enum snmp_op op)164{165int old = 0;166167switch (op) {168169case SNMP_OP_GETNEXT:170abort();171172case SNMP_OP_GET:173break;174175case SNMP_OP_SET:176if (ip_tick < this_tick)177if (fetch_ip() == -1)178return (SNMP_ERR_GENERR);179180switch (value->var.subs[sub - 1]) {181182case LEAF_ipForwarding:183ctx->scratch->int1 = ip_forwarding ? 1 : 2;184ctx->scratch->int2 = value->v.integer;185if (value->v.integer == 1) {186if (!ip_forwarding && ip_forward(1, &old))187return (SNMP_ERR_GENERR);188ctx->scratch->int1 = old ? 1 : 2;189} else if (value->v.integer == 2) {190if (ip_forwarding && ip_forward(0, &old))191return (SNMP_ERR_GENERR);192ctx->scratch->int1 = old;193} else194return (SNMP_ERR_WRONG_VALUE);195break;196197case LEAF_ipDefaultTTL:198ctx->scratch->int1 = ip_defttl;199ctx->scratch->int2 = value->v.integer;200if (value->v.integer < 1 || value->v.integer > 255)201return (SNMP_ERR_WRONG_VALUE);202if (ip_defttl != value->v.integer &&203ip_setttl(value->v.integer, &old))204return (SNMP_ERR_GENERR);205ctx->scratch->int1 = old;206break;207}208return (SNMP_ERR_NOERROR);209210case SNMP_OP_ROLLBACK:211switch (value->var.subs[sub - 1]) {212213case LEAF_ipForwarding:214if (ctx->scratch->int1 == 1) {215if (ctx->scratch->int2 == 2)216(void)ip_forward(1, NULL);217} else {218if (ctx->scratch->int2 == 1)219(void)ip_forward(0, NULL);220}221break;222223case LEAF_ipDefaultTTL:224if (ctx->scratch->int1 != ctx->scratch->int2)225(void)ip_setttl(ctx->scratch->int1, NULL);226break;227}228return (SNMP_ERR_NOERROR);229230case SNMP_OP_COMMIT:231return (SNMP_ERR_NOERROR);232}233234if (ip_tick < this_tick)235if (fetch_ip() == -1)236return (SNMP_ERR_GENERR);237238switch (value->var.subs[sub - 1]) {239240case LEAF_ipForwarding:241value->v.integer = ip_forwarding ? 1 : 2;242break;243244case LEAF_ipDefaultTTL:245value->v.integer = ip_defttl;246break;247}248return (SNMP_ERR_NOERROR);249}250251/*252* READ-ONLY statistics ip group.253*/254int255op_ipstat(struct snmp_context *ctx __unused, struct snmp_value *value,256u_int sub, u_int idx __unused, enum snmp_op op)257{258switch (op) {259260case SNMP_OP_GETNEXT:261abort();262263case SNMP_OP_GET:264break;265266case SNMP_OP_SET:267return (SNMP_ERR_NOT_WRITEABLE);268269case SNMP_OP_ROLLBACK:270case SNMP_OP_COMMIT:271abort();272}273274if (ipstat_tick < this_tick)275fetch_ipstat();276277switch (value->var.subs[sub - 1]) {278279case LEAF_ipInReceives:280value->v.uint32 = ipstat.ips_total;281break;282283case LEAF_ipInHdrErrors:284value->v.uint32 = ipstat.ips_badsum + ipstat.ips_tooshort285+ ipstat.ips_toosmall + ipstat.ips_badhlen286+ ipstat.ips_badlen + ipstat.ips_badvers +287+ ipstat.ips_toolong;288break;289290case LEAF_ipInAddrErrors:291value->v.uint32 = ipstat.ips_cantforward;292break;293294case LEAF_ipForwDatagrams:295value->v.uint32 = ipstat.ips_forward;296break;297298case LEAF_ipInUnknownProtos:299value->v.uint32 = ipstat.ips_noproto;300break;301302case LEAF_ipInDiscards:303value->v.uint32 = ip_idrop;304break;305306case LEAF_ipInDelivers:307value->v.uint32 = ipstat.ips_delivered;308break;309310case LEAF_ipOutRequests:311value->v.uint32 = ipstat.ips_localout;312break;313314case LEAF_ipOutDiscards:315value->v.uint32 = ipstat.ips_odropped;316break;317318case LEAF_ipOutNoRoutes:319value->v.uint32 = ipstat.ips_noroute;320break;321322case LEAF_ipReasmTimeout:323value->v.integer = ip_fragttl;324break;325326case LEAF_ipReasmReqds:327value->v.uint32 = ipstat.ips_fragments;328break;329330case LEAF_ipReasmOKs:331value->v.uint32 = ipstat.ips_reassembled;332break;333334case LEAF_ipReasmFails:335value->v.uint32 = ipstat.ips_fragdropped336+ ipstat.ips_fragtimeout;337break;338339case LEAF_ipFragOKs:340value->v.uint32 = ipstat.ips_fragmented;341break;342343case LEAF_ipFragFails:344value->v.uint32 = ipstat.ips_cantfrag;345break;346347case LEAF_ipFragCreates:348value->v.uint32 = ipstat.ips_ofragments;349break;350}351return (SNMP_ERR_NOERROR);352}353354/*355* READ-ONLY statistics icmp group.356*/357int358op_icmpstat(struct snmp_context *ctx __unused, struct snmp_value *value,359u_int sub, u_int idx __unused, enum snmp_op op)360{361u_int i;362363switch (op) {364365case SNMP_OP_GETNEXT:366abort();367368case SNMP_OP_GET:369break;370371case SNMP_OP_SET:372return (SNMP_ERR_NOT_WRITEABLE);373374case SNMP_OP_ROLLBACK:375case SNMP_OP_COMMIT:376abort();377}378379if (ipstat_tick < this_tick)380fetch_ipstat();381382switch (value->var.subs[sub - 1]) {383384case LEAF_icmpInMsgs:385value->v.integer = 0;386for (i = 0; i <= ICMP_MAXTYPE; i++)387value->v.integer += icmpstat.icps_inhist[i];388value->v.integer += icmpstat.icps_tooshort +389icmpstat.icps_checksum;390/* missing: bad type and packets on faith */391break;392393case LEAF_icmpInErrors:394value->v.integer = icmpstat.icps_tooshort +395icmpstat.icps_checksum +396icmpstat.icps_badlen +397icmpstat.icps_badcode +398icmpstat.icps_bmcastecho +399icmpstat.icps_bmcasttstamp;400break;401402case LEAF_icmpInDestUnreachs:403value->v.integer = icmpstat.icps_inhist[ICMP_UNREACH];404break;405406case LEAF_icmpInTimeExcds:407value->v.integer = icmpstat.icps_inhist[ICMP_TIMXCEED];408break;409410case LEAF_icmpInParmProbs:411value->v.integer = icmpstat.icps_inhist[ICMP_PARAMPROB];412break;413414case LEAF_icmpInSrcQuenchs:415value->v.integer = icmpstat.icps_inhist[ICMP_SOURCEQUENCH];416break;417418case LEAF_icmpInRedirects:419value->v.integer = icmpstat.icps_inhist[ICMP_REDIRECT];420break;421422case LEAF_icmpInEchos:423value->v.integer = icmpstat.icps_inhist[ICMP_ECHO];424break;425426case LEAF_icmpInEchoReps:427value->v.integer = icmpstat.icps_inhist[ICMP_ECHOREPLY];428break;429430case LEAF_icmpInTimestamps:431value->v.integer = icmpstat.icps_inhist[ICMP_TSTAMP];432break;433434case LEAF_icmpInTimestampReps:435value->v.integer = icmpstat.icps_inhist[ICMP_TSTAMPREPLY];436break;437438case LEAF_icmpInAddrMasks:439value->v.integer = icmpstat.icps_inhist[ICMP_MASKREQ];440break;441442case LEAF_icmpInAddrMaskReps:443value->v.integer = icmpstat.icps_inhist[ICMP_MASKREPLY];444break;445446case LEAF_icmpOutMsgs:447value->v.integer = 0;448for (i = 0; i <= ICMP_MAXTYPE; i++)449value->v.integer += icmpstat.icps_outhist[i];450value->v.integer += icmpstat.icps_badaddr +451icmpstat.icps_noroute;452break;453454case LEAF_icmpOutErrors:455value->v.integer = icmpstat.icps_badaddr +456icmpstat.icps_noroute;457break;458459case LEAF_icmpOutDestUnreachs:460value->v.integer = icmpstat.icps_outhist[ICMP_UNREACH];461break;462463case LEAF_icmpOutTimeExcds:464value->v.integer = icmpstat.icps_outhist[ICMP_TIMXCEED];465break;466467case LEAF_icmpOutParmProbs:468value->v.integer = icmpstat.icps_outhist[ICMP_PARAMPROB];469break;470471case LEAF_icmpOutSrcQuenchs:472value->v.integer = icmpstat.icps_outhist[ICMP_SOURCEQUENCH];473break;474475case LEAF_icmpOutRedirects:476value->v.integer = icmpstat.icps_outhist[ICMP_REDIRECT];477break;478479case LEAF_icmpOutEchos:480value->v.integer = icmpstat.icps_outhist[ICMP_ECHO];481break;482483case LEAF_icmpOutEchoReps:484value->v.integer = icmpstat.icps_outhist[ICMP_ECHOREPLY];485break;486487case LEAF_icmpOutTimestamps:488value->v.integer = icmpstat.icps_outhist[ICMP_TSTAMP];489break;490491case LEAF_icmpOutTimestampReps:492value->v.integer = icmpstat.icps_outhist[ICMP_TSTAMPREPLY];493break;494495case LEAF_icmpOutAddrMasks:496value->v.integer = icmpstat.icps_outhist[ICMP_MASKREQ];497break;498499case LEAF_icmpOutAddrMaskReps:500value->v.integer = icmpstat.icps_outhist[ICMP_MASKREPLY];501break;502}503return (SNMP_ERR_NOERROR);504}505506507