mibII_udp.c revision 122394
1122394Sharti/* 2122394Sharti * Copyright (c) 2001-2003 3122394Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4122394Sharti * All rights reserved. 5122394Sharti * 6122394Sharti * Author: Harti Brandt <harti@freebsd.org> 7122394Sharti * 8122394Sharti * Redistribution of this software and documentation and use in source and 9122394Sharti * binary forms, with or without modification, are permitted provided that 10122394Sharti * the following conditions are met: 11122394Sharti * 12122394Sharti * 1. Redistributions of source code or documentation must retain the above 13122394Sharti * copyright notice, this list of conditions and the following disclaimer. 14122394Sharti * 2. Redistributions in binary form must reproduce the above copyright 15122394Sharti * notice, this list of conditions and the following disclaimer in the 16122394Sharti * documentation and/or other materials provided with the distribution. 17122394Sharti * 3. Neither the name of the Institute nor the names of its contributors 18122394Sharti * may be used to endorse or promote products derived from this software 19122394Sharti * without specific prior written permission. 20122394Sharti * 21122394Sharti * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS 22122394Sharti * AND ITS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 23122394Sharti * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 24122394Sharti * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 25122394Sharti * FRAUNHOFER FOKUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26122394Sharti * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27122394Sharti * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 28122394Sharti * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29122394Sharti * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30122394Sharti * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 31122394Sharti * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32122394Sharti * 33122394Sharti * $Begemot: bsnmp/snmp_mibII/mibII_udp.c,v 1.4 2003/01/28 13:44:35 hbb Exp $ 34122394Sharti * 35122394Sharti * udp 36122394Sharti */ 37122394Sharti#include "mibII.h" 38122394Sharti#include "mibII_oid.h" 39122394Sharti#include <sys/socketvar.h> 40122394Sharti#include <netinet/in_pcb.h> 41122394Sharti#include <netinet/udp.h> 42122394Sharti#include <netinet/ip_var.h> 43122394Sharti#include <netinet/udp_var.h> 44122394Sharti 45122394Shartistruct udp_index { 46122394Sharti struct asn_oid index; 47122394Sharti struct xinpcb *inp; 48122394Sharti}; 49122394Sharti 50122394Shartistatic u_int32_t udp_tick; 51122394Shartistatic struct udpstat udpstat; 52122394Shartistatic struct xinpgen *xinpgen; 53122394Shartistatic size_t xinpgen_len; 54122394Shartistatic u_int udp_total; 55122394Sharti 56122394Shartistatic u_int oidnum; 57122394Shartistatic struct udp_index *udpoids; 58122394Sharti 59122394Shartistatic int 60122394Shartiudp_compare(const void *p1, const void *p2) 61122394Sharti{ 62122394Sharti const struct udp_index *t1 = p1; 63122394Sharti const struct udp_index *t2 = p2; 64122394Sharti 65122394Sharti return (asn_compare_oid(&t1->index, &t2->index)); 66122394Sharti} 67122394Sharti 68122394Shartistatic int 69122394Shartifetch_udp(void) 70122394Sharti{ 71122394Sharti size_t len; 72122394Sharti struct xinpgen *ptr; 73122394Sharti struct xinpcb *inp; 74122394Sharti struct udp_index *oid; 75122394Sharti in_addr_t inaddr; 76122394Sharti 77122394Sharti len = sizeof(udpstat); 78122394Sharti if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, NULL, 0) == -1) { 79122394Sharti syslog(LOG_ERR, "net.inet.udp.stats: %m"); 80122394Sharti return (-1); 81122394Sharti } 82122394Sharti if (len != sizeof(udpstat)) { 83122394Sharti syslog(LOG_ERR, "net.inet.udp.stats: wrong size"); 84122394Sharti return (-1); 85122394Sharti } 86122394Sharti 87122394Sharti udp_tick = get_ticks(); 88122394Sharti 89122394Sharti len = 0; 90122394Sharti if (sysctlbyname("net.inet.udp.pcblist", NULL, &len, NULL, 0) == -1) { 91122394Sharti syslog(LOG_ERR, "net.inet.udp.pcblist: %m"); 92122394Sharti return (-1); 93122394Sharti } 94122394Sharti if (len > xinpgen_len) { 95122394Sharti if ((ptr = realloc(xinpgen, len)) == NULL) { 96122394Sharti syslog(LOG_ERR, "%zu: %m", len); 97122394Sharti return (-1); 98122394Sharti } 99122394Sharti xinpgen = ptr; 100122394Sharti xinpgen_len = len; 101122394Sharti } 102122394Sharti if (sysctlbyname("net.inet.udp.pcblist", xinpgen, &len, NULL, 0) == -1) { 103122394Sharti syslog(LOG_ERR, "net.inet.udp.pcblist: %m"); 104122394Sharti return (-1); 105122394Sharti } 106122394Sharti 107122394Sharti udp_total = 0; 108122394Sharti for (ptr = (struct xinpgen *)(void *)((char *)xinpgen + xinpgen->xig_len); 109122394Sharti ptr->xig_len > sizeof(struct xinpgen); 110122394Sharti ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) { 111122394Sharti inp = (struct xinpcb *)ptr; 112122394Sharti if (inp->xi_inp.inp_gencnt > xinpgen->xig_gen || 113122394Sharti (inp->xi_inp.inp_vflag & INP_IPV4) == 0) 114122394Sharti continue; 115122394Sharti 116122394Sharti udp_total++; 117122394Sharti } 118122394Sharti 119122394Sharti if (oidnum < udp_total) { 120122394Sharti oid = realloc(udpoids, udp_total * sizeof(udpoids[0])); 121122394Sharti if (oid == NULL) { 122122394Sharti free(udpoids); 123122394Sharti oidnum = 0; 124122394Sharti return (0); 125122394Sharti } 126122394Sharti udpoids = oid; 127122394Sharti oidnum = udp_total; 128122394Sharti } 129122394Sharti 130122394Sharti oid = udpoids; 131122394Sharti for (ptr = (struct xinpgen *)(void *)((char *)xinpgen + xinpgen->xig_len); 132122394Sharti ptr->xig_len > sizeof(struct xinpgen); 133122394Sharti ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) { 134122394Sharti inp = (struct xinpcb *)ptr; 135122394Sharti if (inp->xi_inp.inp_gencnt > xinpgen->xig_gen || 136122394Sharti (inp->xi_inp.inp_vflag & INP_IPV4) == 0) 137122394Sharti continue; 138122394Sharti oid->inp = inp; 139122394Sharti oid->index.len = 5; 140122394Sharti inaddr = ntohl(inp->xi_inp.inp_laddr.s_addr); 141122394Sharti oid->index.subs[0] = (inaddr >> 24) & 0xff; 142122394Sharti oid->index.subs[1] = (inaddr >> 16) & 0xff; 143122394Sharti oid->index.subs[2] = (inaddr >> 8) & 0xff; 144122394Sharti oid->index.subs[3] = (inaddr >> 0) & 0xff; 145122394Sharti oid->index.subs[4] = ntohs(inp->xi_inp.inp_lport); 146122394Sharti oid++; 147122394Sharti } 148122394Sharti 149122394Sharti qsort(udpoids, udp_total, sizeof(udpoids[0]), udp_compare); 150122394Sharti 151122394Sharti return (0); 152122394Sharti} 153122394Sharti 154122394Shartiint 155122394Shartiop_udp(struct snmp_context *ctx __unused, struct snmp_value *value, 156122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 157122394Sharti{ 158122394Sharti switch (op) { 159122394Sharti 160122394Sharti case SNMP_OP_GETNEXT: 161122394Sharti abort(); 162122394Sharti 163122394Sharti case SNMP_OP_GET: 164122394Sharti break; 165122394Sharti 166122394Sharti case SNMP_OP_SET: 167122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 168122394Sharti 169122394Sharti case SNMP_OP_ROLLBACK: 170122394Sharti case SNMP_OP_COMMIT: 171122394Sharti abort(); 172122394Sharti } 173122394Sharti 174122394Sharti if (udp_tick < this_tick) 175122394Sharti if (fetch_udp() == -1) 176122394Sharti return (SNMP_ERR_GENERR); 177122394Sharti 178122394Sharti switch (value->var.subs[sub - 1]) { 179122394Sharti 180122394Sharti case LEAF_udpInDatagrams: 181122394Sharti value->v.uint32 = udpstat.udps_ipackets; 182122394Sharti break; 183122394Sharti 184122394Sharti case LEAF_udpNoPorts: 185122394Sharti value->v.uint32 = udpstat.udps_noport + 186122394Sharti udpstat.udps_noportbcast + 187122394Sharti udpstat.udps_noportmcast; 188122394Sharti break; 189122394Sharti 190122394Sharti case LEAF_udpInErrors: 191122394Sharti value->v.uint32 = udpstat.udps_hdrops + 192122394Sharti udpstat.udps_badsum + 193122394Sharti udpstat.udps_badlen + 194122394Sharti udpstat.udps_fullsock; 195122394Sharti break; 196122394Sharti 197122394Sharti case LEAF_udpOutDatagrams: 198122394Sharti value->v.uint32 = udpstat.udps_opackets; 199122394Sharti break; 200122394Sharti } 201122394Sharti return (SNMP_ERR_NOERROR); 202122394Sharti} 203122394Sharti 204122394Shartiint 205122394Shartiop_udptable(struct snmp_context *ctx __unused, struct snmp_value *value, 206122394Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 207122394Sharti{ 208122394Sharti u_int i; 209122394Sharti 210122394Sharti if (udp_tick < this_tick) 211122394Sharti if (fetch_udp() == -1) 212122394Sharti return (SNMP_ERR_GENERR); 213122394Sharti 214122394Sharti switch (op) { 215122394Sharti 216122394Sharti case SNMP_OP_GETNEXT: 217122394Sharti for (i = 0; i < udp_total; i++) 218122394Sharti if (index_compare(&value->var, sub, &udpoids[i].index) < 0) 219122394Sharti break; 220122394Sharti if (i == udp_total) 221122394Sharti return (SNMP_ERR_NOSUCHNAME); 222122394Sharti index_append(&value->var, sub, &udpoids[i].index); 223122394Sharti break; 224122394Sharti 225122394Sharti case SNMP_OP_GET: 226122394Sharti for (i = 0; i < udp_total; i++) 227122394Sharti if (index_compare(&value->var, sub, &udpoids[i].index) == 0) 228122394Sharti break; 229122394Sharti if (i == udp_total) 230122394Sharti return (SNMP_ERR_NOSUCHNAME); 231122394Sharti break; 232122394Sharti 233122394Sharti case SNMP_OP_SET: 234122394Sharti return (SNMP_ERR_NOT_WRITEABLE); 235122394Sharti 236122394Sharti case SNMP_OP_ROLLBACK: 237122394Sharti case SNMP_OP_COMMIT: 238122394Sharti default: 239122394Sharti abort(); 240122394Sharti } 241122394Sharti 242122394Sharti switch (value->var.subs[sub - 1]) { 243122394Sharti 244122394Sharti case LEAF_udpLocalAddress: 245122394Sharti value->v.ipaddress[0] = udpoids[i].index.subs[0]; 246122394Sharti value->v.ipaddress[1] = udpoids[i].index.subs[1]; 247122394Sharti value->v.ipaddress[2] = udpoids[i].index.subs[2]; 248122394Sharti value->v.ipaddress[3] = udpoids[i].index.subs[3]; 249122394Sharti break; 250122394Sharti 251122394Sharti case LEAF_udpLocalPort: 252122394Sharti value->v.integer = udpoids[i].index.subs[4]; 253122394Sharti break; 254122394Sharti 255122394Sharti } 256122394Sharti return (SNMP_ERR_NOERROR); 257122394Sharti} 258