1 /* 2 * Copyright (c) 2001-2003 3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4 * All rights reserved. 5 * 6 * Author: Harti Brandt <harti@freebsd.org> 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_nettomedia.c,v 1.8 2004/08/06 08:47:03 brandt Exp $ 30 * 31 * Read-only implementation of the Arp table (ipNetToMediaTable) 32 * 33 * The problem with the table is, that we don't receive routing message 34 * when a) an arp table entry is resolved and b) when an arp table entry is 35 * deleted automatically. Therefor we need to poll the table from time to 36 * time. 37 */ 38 #include "mibII.h" 39 #include "mibII_oid.h" 40 41 #define ARPREFRESH 30 42 43 struct mibarp * 44 mib_find_arp(const struct mibif *ifp, struct in_addr in) 45 { 46 struct mibarp *at; 47 uint32_t a = ntohl(in.s_addr); 48 49 if (get_ticks() >= mibarpticks + ARPREFRESH) 50 mib_arp_update(); 51 52 TAILQ_FOREACH(at, &mibarp_list, link) 53 if (at->index.subs[0] == ifp->index && 54 (at->index.subs[1] == ((a >> 24) & 0xff)) && 55 (at->index.subs[2] == ((a >> 16) & 0xff)) && 56 (at->index.subs[3] == ((a >> 8) & 0xff)) && 57 (at->index.subs[4] == ((a >> 0) & 0xff))) 58 return (at); 59 return (NULL); 60 } 61 62 struct mibarp * 63 mib_arp_create(const struct mibif *ifp, struct in_addr in, const u_char *phys, 64 size_t physlen) 65 { 66 struct mibarp *at; 67 uint32_t a = ntohl(in.s_addr); 68 69 if ((at = malloc(sizeof(*at))) == NULL) 70 return (NULL); 71 at->flags = 0; 72 73 at->index.len = 5; 74 at->index.subs[0] = ifp->index; 75 at->index.subs[1] = (a >> 24) & 0xff; 76 at->index.subs[2] = (a >> 16) & 0xff; 77 at->index.subs[3] = (a >> 8) & 0xff; 78 at->index.subs[4] = (a >> 0) & 0xff; 79 if ((at->physlen = physlen) > sizeof(at->phys)) 80 at->physlen = sizeof(at->phys); 81 memcpy(at->phys, phys, at->physlen); 82 83 INSERT_OBJECT_OID(at, &mibarp_list); 84 85 return (at); 86 } 87 88 void 89 mib_arp_delete(struct mibarp *at) 90 { 91 TAILQ_REMOVE(&mibarp_list, at, link); 92 free(at); 93 } 94 95 int 96 op_nettomedia(struct snmp_context *ctx __unused, struct snmp_value *value, 97 u_int sub, u_int iidx __unused, enum snmp_op op) 98 { 99 struct mibarp *at; 100 101 at = NULL; /* gcc */ 102 103 if (get_ticks() >= mibarpticks + ARPREFRESH) 104 mib_arp_update(); 105 106 switch (op) { 107 108 case SNMP_OP_GETNEXT: 109 if ((at = NEXT_OBJECT_OID(&mibarp_list, &value->var, sub)) == NULL) 110 return (SNMP_ERR_NOSUCHNAME); 111 index_append(&value->var, sub, &at->index); 112 break; 113 114 case SNMP_OP_GET: 115 if ((at = FIND_OBJECT_OID(&mibarp_list, &value->var, sub)) == NULL) 116 return (SNMP_ERR_NOSUCHNAME); 117 break; 118 119 case SNMP_OP_SET: 120 if ((at = FIND_OBJECT_OID(&mibarp_list, &value->var, sub)) == NULL) 121 return (SNMP_ERR_NO_CREATION); 122 return (SNMP_ERR_NOT_WRITEABLE); 123 124 case SNMP_OP_ROLLBACK: 125 case SNMP_OP_COMMIT: 126 abort(); 127 } 128 129 switch (value->var.subs[sub - 1]) { 130 131 case LEAF_ipNetToMediaIfIndex: 132 value->v.integer = at->index.subs[0]; 133 break; 134 135 case LEAF_ipNetToMediaPhysAddress: 136 return (string_get(value, at->phys, at->physlen)); 137 138 case LEAF_ipNetToMediaNetAddress: 139 value->v.ipaddress[0] = at->index.subs[1]; 140 value->v.ipaddress[1] = at->index.subs[2]; 141 value->v.ipaddress[2] = at->index.subs[3]; 142 value->v.ipaddress[3] = at->index.subs[4]; 143 break; 144 145 case LEAF_ipNetToMediaType: 146 value->v.integer = (at->flags & MIBARP_PERM) ? 4 : 3; 147 break; 148 } 149 return (SNMP_ERR_NOERROR); 150 } 151