2
* Template MIB group implementation - at.c
6
/* Portions of this file are subject to the following copyright(s). See
7
* the Net-SNMP's COPYING file for more details and other copyrights
11
* Portions of this file are copyrighted by:
12
* Copyright ļæ½ 2003 Sun Microsystems, Inc. All rights reserved.
13
* Use is subject to license terms specified in the COPYING file
14
* distributed with the Net-SNMP package.
17
#include <net-snmp/net-snmp-config.h>
26
#if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL)
28
#define _I_DEFINED_KERNEL
30
#include <sys/types.h>
31
#if TIME_WITH_SYS_TIME
33
# include <sys/timeb.h>
35
# include <sys/time.h>
40
# include <sys/time.h>
46
#include <sys/socket.h>
50
#include <netinet/in.h>
56
#include <net/if_var.h>
58
#ifdef _I_DEFINED_KERNEL
62
#if HAVE_NETINET_IF_ETHER_H
63
#include <netinet/if_ether.h>
66
#include <inet/mib2.h>
69
#include <sys/param.h>
72
#include <sys/sysctl.h>
76
#include <net/if_dl.h>
78
#include <sys/net/if_dl.h>
82
#include <sys/stream.h>
85
#include <net/route.h>
88
#include "kernel_sunos5.h"
99
#include <netinet/mib_kern.h>
102
#include <net-snmp/net-snmp-includes.h>
103
#include <net-snmp/agent/net-snmp-agent-includes.h>
104
#include <net-snmp/agent/auto_nlist.h>
107
#include "interfaces.h"
109
#if defined(HAVE_SYS_SYSCTL_H) && !defined(CAN_USE_SYSCTL)
110
# if defined(RTF_LLINFO) && !defined(irix6)
111
# define CAN_USE_SYSCTL 1
120
/*********************
122
* Kernel & interface information,
123
* and internal forward declarations
125
*********************/
129
static void ARP_Scan_Init(void);
130
#ifdef ARP_SCAN_FOUR_ARGUMENTS
131
static int ARP_Scan_Next(u_long *, char *, u_long *, u_short *);
133
static int ARP_Scan_Next(u_long *, char *, u_long *);
138
/*********************
140
* Public interface functions
142
*********************/
145
* define the structure we're going to ask the agent to register our
148
struct variable1 at_variables[] = {
149
{ATIFINDEX, ASN_INTEGER, RONLY, var_atEntry, 1, {1}},
150
{ATPHYSADDRESS, ASN_OCTET_STR, RONLY, var_atEntry, 1, {2}},
151
{ATNETADDRESS, ASN_IPADDRESS, RONLY, var_atEntry, 1, {3}}
155
* Define the OID pointer to the top of the mib tree that we're
156
* registering underneath
158
oid at_variables_oid[] = { SNMP_OID_MIB2, 3, 1, 1 };
164
* register ourselves with the agent to handle our mib tree
166
REGISTER_MIB("mibII/at", at_variables, variable1, at_variables_oid);
168
init_kernel_sunos5();
178
* vp IN - pointer to variable entry that points here
179
* name IN/OUT - IN/name requested, OUT/name found
180
* length IN/OUT - length of IN/OUT oid's
181
* exact IN - TRUE if an exact match was requested
182
* var_len OUT - length of variable or 0 if function returned
188
var_atEntry(struct variable *vp,
191
int exact, size_t * var_len, WriteMethod ** write_method)
194
* Address Translation table object identifier is of form:
195
* 1.3.6.1.2.1.3.1.1.1.interface.1.A.B.C.D, where A.B.C.D is IP address.
196
* Interface is at offset 10,
197
* IPADDR starts at offset 12.
199
* IP Net to Media table object identifier is of form:
200
* 1.3.6.1.2.1.4.22.1.1.1.interface.A.B.C.D, where A.B.C.D is IP address.
201
* Interface is at offset 10,
202
* IPADDR starts at offset 11.
208
static char PhysAddr[6], LowPhysAddr[6];
209
u_long Addr, LowAddr, foundone;
210
#ifdef ARP_SCAN_FOUR_ARGUMENTS
211
u_short ifIndex, lowIfIndex = 0;
212
#endif /* ARP_SCAN_FOUR_ARGUMENTS */
213
u_long ifType, lowIfType = 0;
218
* fill in object part of name for current (less sizeof instance part)
220
memcpy((char *) current, (char *) vp->name,
221
(int) vp->namelen * sizeof(oid));
223
if (current[6] == 3) { /* AT group oid */
225
} else { /* IP NetToMedia group oid */
229
LowAddr = 0; /* Don't have one yet */
233
#ifdef ARP_SCAN_FOUR_ARGUMENTS
234
if (ARP_Scan_Next(&Addr, PhysAddr, &ifType, &ifIndex) == 0)
236
current[10] = ifIndex;
238
if (current[6] == 3) { /* AT group oid */
241
} else { /* IP NetToMedia group oid */
244
#else /* ARP_SCAN_FOUR_ARGUMENTS */
245
if (ARP_Scan_Next(&Addr, PhysAddr, &ifType) == 0)
249
if (current[6] == 3) { /* AT group oid */
252
} else { /* IP NetToMedia group oid */
255
#endif /* ARP_SCAN_FOUR_ARGUMENTS */
256
cp = (u_char *) & Addr;
263
if (snmp_oid_compare(current, oid_length, name, *length) == 0) {
264
memcpy((char *) lowest, (char *) current,
265
oid_length * sizeof(oid));
268
#ifdef ARP_SCAN_FOUR_ARGUMENTS
269
lowIfIndex = ifIndex;
270
#endif /* ARP_SCAN_FOUR_ARGUMENTS */
271
memcpy(LowPhysAddr, PhysAddr, sizeof(PhysAddr));
273
break; /* no need to search further */
276
if ((snmp_oid_compare(current, oid_length, name, *length) > 0)
280
(current, oid_length, lowest, oid_length) < 0))) {
282
* if new one is greater than input and closer to input than
283
* previous lowest, save this one as the "next" one.
285
memcpy((char *) lowest, (char *) current,
286
oid_length * sizeof(oid));
289
#ifdef ARP_SCAN_FOUR_ARGUMENTS
290
lowIfIndex = ifIndex;
291
#endif /* ARP_SCAN_FOUR_ARGUMENTS */
292
memcpy(LowPhysAddr, PhysAddr, sizeof(PhysAddr));
300
memcpy((char *) name, (char *) lowest, oid_length * sizeof(oid));
301
*length = oid_length;
304
case IPMEDIAIFINDEX: /* also ATIFINDEX */
305
*var_len = sizeof long_return;
306
#ifdef ARP_SCAN_FOUR_ARGUMENTS
307
long_return = lowIfIndex;
308
#else /* ARP_SCAN_FOUR_ARGUMENTS */
312
long_return = 1; /* XXX */
313
#endif /* ARP_SCAN_FOUR_ARGUMENTS */
314
return (u_char *) & long_return;
315
case IPMEDIAPHYSADDRESS: /* also ATPHYSADDRESS */
316
*var_len = sizeof(LowPhysAddr);
317
return (u_char *) LowPhysAddr;
318
case IPMEDIANETADDRESS: /* also ATNETADDRESS */
319
*var_len = sizeof long_return;
320
long_return = LowAddr;
321
return (u_char *) & long_return;
323
*var_len = sizeof long_return;
324
long_return = lowIfType;
325
return (u_char *) & long_return;
327
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n",
334
typedef struct if_ip {
340
AT_Cmp(void *addr, void *ep)
342
mib2_ipNetToMediaEntry_t *mp = (mib2_ipNetToMediaEntry_t *) ep;
344
DEBUGMSGTL(("mibII/at", "......... AT_Cmp %lx<>%lx %d<>%d (%.5s)\n",
345
mp->ipNetToMediaNetAddress, ((if_ip_t *) addr)->ipAddr,
346
((if_ip_t *) addr)->ifIdx,
347
Interface_Index_By_Name(mp->ipNetToMediaIfIndex.o_bytes,
348
mp->ipNetToMediaIfIndex.o_length),
349
mp->ipNetToMediaIfIndex.o_bytes));
350
if (mp->ipNetToMediaNetAddress != ((if_ip_t *) addr)->ipAddr)
352
else if (((if_ip_t *) addr)->ifIdx !=
353
Interface_Index_By_Name(mp->ipNetToMediaIfIndex.o_bytes,
354
mp->ipNetToMediaIfIndex.o_length))
358
DEBUGMSGTL(("mibII/at", "......... AT_Cmp returns %d\n", ret));
363
var_atEntry(struct variable * vp,
366
int exact, size_t * var_len, WriteMethod ** write_method)
369
* object identifier is of form:
370
* 1.3.6.1.2.1.3.1.1.1.interface.1.A.B.C.D, where A.B.C.D is IP address.
371
* Interface is at offset 10,
372
* IPADDR starts at offset 12.
374
#define AT_MAX_NAME_LENGTH 16
375
#define AT_IFINDEX_OFF 10
378
oid lowest[AT_MAX_NAME_LENGTH];
379
oid current[AT_MAX_NAME_LENGTH];
381
mib2_ipNetToMediaEntry_t entry;
382
static mib2_ipNetToMediaEntry_t Lowentry;
388
* fill in object part of name for current (less sizeof instance part)
391
DEBUGMSGTL(("mibII/at", "var_atEntry: "));
392
DEBUGMSGOID(("mibII/at", vp->name, vp->namelen));
393
DEBUGMSG(("mibII/at", " %d\n", exact));
395
memset(&Lowentry, 0, sizeof(Lowentry));
396
memcpy((char *) current, (char *) vp->name, vp->namelen * sizeof(oid));
398
for (NextAddr.ipAddr = (u_long) - 1, NextAddr.ifIdx = 255, req_type =
400
NextAddr.ipAddr = entry.ipNetToMediaNetAddress, NextAddr.ifIdx =
401
current[AT_IFINDEX_OFF], req_type = GET_NEXT) {
403
(MIB_IP_NET, &entry, sizeof(mib2_ipNetToMediaEntry_t),
404
req_type, &AT_Cmp, &NextAddr) != 0)
406
current[AT_IFINDEX_OFF] =
407
Interface_Index_By_Name(entry.ipNetToMediaIfIndex.o_bytes,
408
entry.ipNetToMediaIfIndex.o_length);
409
if (current[6] == 3) { /* AT group oid */
410
current[AT_IFINDEX_OFF + 1] = 1;
411
offset = AT_IFINDEX_OFF + 2;
412
olength = AT_IFINDEX_OFF + 6;
414
offset = AT_IFINDEX_OFF + 1;
415
olength = AT_IFINDEX_OFF + 5;
417
COPY_IPADDR(cp, (u_char *) & entry.ipNetToMediaNetAddress, op,
420
if (snmp_oid_compare(current, olength, name, *length) == 0) {
421
memcpy((char *) lowest, (char *) current,
422
olength * sizeof(oid));
425
break; /* no need to search further */
428
if (snmp_oid_compare(current, olength, name, *length) > 0
429
&& snmp_oid_compare(current, olength, lowest,
432
* if new one is greater than input and closer to input than
433
* previous lowest, and is not equal to it, save this one as the "next" one.
435
memcpy((char *) lowest, (char *) current,
436
olength * sizeof(oid));
442
DEBUGMSGTL(("mibII/at", "... Found = %d\n", Found));
445
memcpy((char *) name, (char *) lowest, olength * sizeof(oid));
450
*var_len = sizeof long_return;
452
Interface_Index_By_Name(Lowentry.ipNetToMediaIfIndex.o_bytes,
453
Lowentry.ipNetToMediaIfIndex.o_length);
454
return (u_char *) & long_return;
455
case IPMEDIAPHYSADDRESS:
456
*var_len = Lowentry.ipNetToMediaPhysAddress.o_length;
457
return Lowentry.ipNetToMediaPhysAddress.o_bytes;
458
case IPMEDIANETADDRESS:
459
*var_len = sizeof(Lowentry.ipNetToMediaNetAddress);
460
return (u_char *) &Lowentry.ipNetToMediaNetAddress;
462
*var_len = sizeof long_return;
463
long_return = Lowentry.ipNetToMediaType;
464
return (u_char *) & long_return;
466
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n",
471
#endif /* solaris2 */
474
/*********************
476
* Internal implementation functions
478
*********************/
482
static int arptab_size, arptab_current;
484
static char *lim, *rtnext;
487
#ifdef STRUCT_ARPHD_HAS_AT_NEXT
488
static struct arphd *at = 0;
489
static struct arptab *at_ptr, at_entry;
490
static struct arpcom at_com;
491
#elif defined(hpux11)
492
static mib_ipNetToMediaEnt *at = (mib_ipNetToMediaEnt *) 0;
496
* at used to be allocated every time we needed to look at the arp cache.
497
* This cause us to parse /proc/net/arp twice for each request and didn't
498
* allow us to filter things like we'd like to. So now we use it
499
* semi-statically. We initialize it to size 0 and if we need more room
500
* we realloc room for ARP_CACHE_INCR more entries in the table.
501
* We never release what we've taken . . .
503
#define ARP_CACHE_INCR 1024
504
static struct arptab *at = NULL;
505
static int arptab_curr_max_size = 0;
508
#endif /* CAN_USE_SYSCTL */
513
#ifndef CAN_USE_SYSCTL
525
at = (mib_ipNetToMediaEnt *) 0;
528
if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) {
529
p.objid = ID_ipNetToMediaTableNum;
530
p.buffer = (void *) &val;
533
if ((ret = get_mib_info(fd, &p)) == 0)
536
if (arptab_size > 0) {
537
ulen = (unsigned) arptab_size *sizeof(mib_ipNetToMediaEnt);
538
at = (mib_ipNetToMediaEnt *) malloc(ulen);
539
p.objid = ID_ipNetToMediaTable;
540
p.buffer = (void *) at;
542
if ((ret = get_mib_info(fd, &p)) < 0)
554
auto_nlist(ARPTAB_SIZE_SYMBOL, (char *) &arptab_size,
556
#ifdef STRUCT_ARPHD_HAS_AT_NEXT
557
at = (struct arphd *) malloc(arptab_size * sizeof(struct arphd));
559
at = (struct arptab *) malloc(arptab_size * sizeof(struct arptab));
562
#ifdef STRUCT_ARPHD_HAS_AT_NEXT
563
auto_nlist(ARPTAB_SYMBOL, (char *) at,
564
arptab_size * sizeof(struct arphd));
565
at_ptr = at[0].at_next;
567
auto_nlist(ARPTAB_SYMBOL, (char *) at,
568
arptab_size * sizeof(struct arptab));
575
static time_t tm = 0; /* Time of last scan */
579
int za, zb, zc, zd, ze, zf, zg, zh, zi, zj;
582
arptab_current = 0; /* Anytime this is called we need to reset 'current' */
584
if (time(NULL) < tm + 1) { /*Our cool one second cache implementation :-) */
588
in = fopen("/proc/net/arp", "r");
590
snmp_log(LOG_ERR, "snmpd: Cannot open /proc/net/arp\n");
596
* Get rid of the header line
598
fgets(line, sizeof(line), in);
601
while (fgets(line, sizeof(line), in)) {
604
if (i >= arptab_curr_max_size) {
605
struct arptab *newtab = (struct arptab *)
606
realloc(at, (sizeof(struct arptab) *
607
(arptab_curr_max_size + ARP_CACHE_INCR)));
610
"Error allocating more space for arpcache. "
611
"Cache will continue to be limited to %d entries",
612
arptab_curr_max_size);
615
arptab_curr_max_size += ARP_CACHE_INCR;
621
"%d.%d.%d.%d 0x%*x 0x%x %x:%x:%x:%x:%x:%x %*[^ ] %20s\n",
622
&za, &zb, &zc, &zd, &tmp_flags, &ze, &zf, &zg, &zh, &zi,
624
snmp_log(LOG_ERR, "Bad line in /proc/net/arp: %s", line);
628
* Invalidated entries have their flag set to 0.
629
* * We want to ignore them
631
if (tmp_flags == 0) {
634
at[i].at_flags = tmp_flags;
635
at[i].at_enaddr[0] = ze;
636
at[i].at_enaddr[1] = zf;
637
at[i].at_enaddr[2] = zg;
638
at[i].at_enaddr[3] = zh;
639
at[i].at_enaddr[4] = zi;
640
at[i].at_enaddr[5] = zj;
641
tmp_a = ((u_long) za << 24) |
642
((u_long) zb << 16) | ((u_long) zc << 8) | ((u_long) zd);
643
at[i].at_iaddr.s_addr = htonl(tmp_a);
644
at[i].if_index = Interface_Index_By_Name(ifname, strlen(ifname));
652
#else /* CAN_USE_SYSCTL */
661
mib[4] = NET_RT_FLAGS;
666
rtnext = lim = at = 0;
668
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
669
snmp_log_perror("route-sysctl-estimate");
671
if ((at = malloc(needed ? needed : 1)) == NULL)
672
snmp_log_perror("malloc");
674
if (sysctl(mib, 6, at, &needed, NULL, 0) < 0)
675
snmp_log_perror("actual retrieval of routing table");
683
#endif /* CAN_USE_SYSCTL */
686
#ifdef ARP_SCAN_FOUR_ARGUMENTS
688
ARP_Scan_Next(u_long * IPAddr, char *PhysAddr, u_long * ifType,
692
ARP_Scan_Next(u_long * IPAddr, char *PhysAddr, u_long * ifType)
695
#ifndef CAN_USE_SYSCTL
697
if (arptab_current < arptab_size) {
701
*IPAddr = at[arptab_current].at_iaddr.s_addr;
704
at_flags & ATF_PERM) ? 4 /*static */ : 3 /*dynamic */ ;
705
*ifIndex = at[arptab_current].if_index;
706
memcpy(PhysAddr, &at[arptab_current].at_enaddr,
707
sizeof(at[arptab_current].at_enaddr));
710
* increment to point next entry
718
#elif defined(hpux11)
719
if (arptab_current < arptab_size) {
723
*IPAddr = at[arptab_current].NetAddr;
724
memcpy(PhysAddr, at[arptab_current].PhysAddr.o_bytes,
725
at[arptab_current].PhysAddr.o_length);
726
*ifType = at[arptab_current].Type;
727
*ifIndex = at[arptab_current].IfIndex;
729
* increment to point next entry
737
#elif !defined(ARP_SCAN_FOUR_ARGUMENTS) || defined(hpux)
738
register struct arptab *atab;
740
while (arptab_current < arptab_size) {
741
#ifdef STRUCT_ARPHD_HAS_AT_NEXT
743
* The arp table is an array of linked lists of arptab entries.
744
* Unused slots have pointers back to the array entry itself
747
if (at_ptr == (auto_nlist_value(ARPTAB_SYMBOL) +
748
arptab_current * sizeof(struct arphd))) {
753
at_ptr = at[arptab_current].at_next;
757
klookup(at_ptr, (char *) &at_entry, sizeof(struct arptab));
758
klookup(at_entry.at_ac, (char *) &at_com, sizeof(struct arpcom));
760
at_ptr = at_entry.at_next;
762
*ifIndex = at_com.ac_if.if_index; /* not strictly ARPHD */
763
#else /* STRUCT_ARPHD_HAS_AT_NEXT */
764
atab = &at[arptab_current++];
765
#endif /* STRUCT_ARPHD_HAS_AT_NEXT */
766
if (!(atab->at_flags & ATF_COM))
768
*ifType = (atab->at_flags & ATF_PERM) ? 4 : 3;
769
*IPAddr = atab->at_iaddr.s_addr;
770
#if defined (sunV3) || defined(sparc) || defined(hpux)
771
memcpy(PhysAddr, (char *) &atab->at_enaddr,
772
sizeof(atab->at_enaddr));
774
#if defined(mips) || defined(ibm032)
775
memcpy(PhysAddr, (char *) atab->at_enaddr,
776
sizeof(atab->at_enaddr));
780
#endif /* linux || hpux11 || !ARP_SCAN_FOUR_ARGUMENTS || hpux */
782
return 0; /* we need someone with an irix box to fix this section */
784
#else /* !CAN_USE_SYSCTL */
785
struct rt_msghdr *rtm;
786
struct sockaddr_inarp *sin;
787
struct sockaddr_dl *sdl;
789
while (rtnext < lim) {
790
rtm = (struct rt_msghdr *) rtnext;
791
sin = (struct sockaddr_inarp *) (rtm + 1);
792
sdl = (struct sockaddr_dl *) (sin + 1);
793
rtnext += rtm->rtm_msglen;
795
*IPAddr = sin->sin_addr.s_addr;
796
memcpy(PhysAddr, (char *) LLADDR(sdl), sdl->sdl_alen);
797
*ifIndex = sdl->sdl_index;
798
*ifType = 1; /* XXX */
802
return (0); /* "EOF" */
803
#endif /* !CAN_USE_SYSCTL */
805
#endif /* solaris2 */
808
#include <iphlpapi.h>
810
extern WriteMethod write_arp;
811
MIB_IPNETROW *arp_row = NULL;
815
var_atEntry(struct variable *vp,
818
int exact, size_t * var_len, WriteMethod ** write_method)
821
* Address Translation table object identifier is of form:
822
* 1.3.6.1.2.1.3.1.?.interface.1.A.B.C.D, where A.B.C.D is IP address.
823
* Interface is at offset 10,
824
* IPADDR starts at offset 12.
826
* IP Net to Media table object identifier is of form:
827
* 1.3.6.1.2.1.4.22.1.?.interface.A.B.C.D, where A.B.C.D is IP address.
828
* Interface is at offset 10,
829
* IPADDR starts at offset 11.
836
int lowState = -1; /* Don't have one yet */
837
PMIB_IPNETTABLE pIpNetTable = NULL;
838
DWORD status = NO_ERROR;
839
DWORD dwActualSize = 0;
844
* fill in object part of name for current (less sizeof instance part)
846
memcpy((char *) current, (char *) vp->name,
847
(int) vp->namelen * sizeof(oid));
849
if (current[6] == 3) { /* AT group oid */
851
} else { /* IP NetToMedia group oid */
855
status = GetIpNetTable(pIpNetTable, &dwActualSize, TRUE);
856
if (status == ERROR_INSUFFICIENT_BUFFER) {
857
pIpNetTable = (PMIB_IPNETTABLE) malloc(dwActualSize);
858
if (pIpNetTable != NULL) {
860
* Get the sorted IpNet Table
862
status = GetIpNetTable(pIpNetTable, &dwActualSize, TRUE);
867
if (status == NO_ERROR) {
868
for (i = 0; i < pIpNetTable->dwNumEntries; ++i) {
869
current[10] = pIpNetTable->table[i].dwIndex;
872
if (current[6] == 3) { /* AT group oid */
875
} else { /* IP NetToMedia group oid */
878
cp = (u_char *) & pIpNetTable->table[i].dwAddr;
885
if (snmp_oid_compare(current, oid_length, name, *length) ==
887
memcpy((char *) lowest, (char *) current,
888
oid_length * sizeof(oid));
890
break; /* no need to search further */
893
if (snmp_oid_compare(current, oid_length, name, *length) >
895
memcpy((char *) lowest, (char *) current,
896
oid_length * sizeof(oid));
898
break; /* As the table is sorted, no need to search further */
903
if (arp_row == NULL) {
905
* Free allocated memory in case of SET request's FREE phase
907
arp_row = (PMIB_IPNETROW) malloc(sizeof(MIB_IPNETROW));
910
if (lowState < 0 || status != NO_ERROR) {
912
* for creation of new row, only ipNetToMediaTable case is considered
914
if (*length == 15 || *length == 16) {
916
*write_method = write_arp;
917
arp_row->dwIndex = name[10];
919
if (*length == 15) { /* ipNetToMediaTable */
921
} else { /* at Table */
926
dest_addr[0] = (u_char) name[i];
927
dest_addr[1] = (u_char) name[i + 1];
928
dest_addr[2] = (u_char) name[i + 2];
929
dest_addr[3] = (u_char) name[i + 3];
930
arp_row->dwAddr = *((DWORD *) dest_addr);
932
arp_row->dwType = 4; /* Static */
933
arp_row->dwPhysAddrLen = 0;
940
memcpy((char *) name, (char *) lowest, oid_length * sizeof(oid));
941
*length = oid_length;
942
*write_method = write_arp;
943
*arp_row = pIpNetTable->table[i];
946
case IPMEDIAIFINDEX: /* also ATIFINDEX */
947
*var_len = sizeof long_return;
948
long_return = pIpNetTable->table[i].dwIndex;
950
return (u_char *) & long_return;
951
case IPMEDIAPHYSADDRESS: /* also ATPHYSADDRESS */
952
*var_len = pIpNetTable->table[i].dwPhysAddrLen;
953
memcpy(return_buf, pIpNetTable->table[i].bPhysAddr, *var_len);
955
return (u_char *) return_buf;
956
case IPMEDIANETADDRESS: /* also ATNETADDRESS */
957
*var_len = sizeof long_return;
958
long_return = pIpNetTable->table[i].dwAddr;
960
return (u_char *) & long_return;
962
*var_len = sizeof long_return;
963
long_return = pIpNetTable->table[i].dwType;
965
return (u_char *) & long_return;
967
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n",
974
write_arp(int action,
977
size_t var_val_len, u_char * statP, oid * name, size_t length)
979
int var, retval = SNMP_ERR_NOERROR;
980
static PMIB_IPNETROW oldarp_row = NULL;
981
MIB_IPNETROW temp_row;
982
DWORD status = NO_ERROR;
985
* IP Net to Media table object identifier is of form:
986
* 1.3.6.1.2.1.4.22.1.?.interface.A.B.C.D, where A.B.C.D is IP address.
987
* Interface is at offset 10,
988
* IPADDR starts at offset 11.
991
if (name[6] == 3) { /* AT group oid */
993
snmp_log(LOG_ERR, "length error\n");
994
return SNMP_ERR_NOCREATION;
996
} else { /* IP NetToMedia group oid */
998
snmp_log(LOG_ERR, "length error\n");
999
return SNMP_ERR_NOCREATION;
1005
* #define for ipNetToMediaTable entries are 1 less than corresponding sub-id in MIB
1006
* * i.e. IPMEDIAIFINDEX defined as 0, but ipNetToMediaIfIndex registered as 1
1012
case IPMEDIAIFINDEX:
1013
if (var_val_type != ASN_INTEGER) {
1014
snmp_log(LOG_ERR, "not integer\n");
1015
return SNMP_ERR_WRONGTYPE;
1017
if ((*((int *) var_val)) < 0) {
1018
snmp_log(LOG_ERR, "invalid media ifIndex");
1019
return SNMP_ERR_WRONGVALUE;
1021
if (var_val_len > sizeof(int)) {
1022
snmp_log(LOG_ERR, "bad length\n");
1023
return SNMP_ERR_WRONGLENGTH;
1026
case IPMEDIANETADDRESS:
1027
if (var_val_type != ASN_IPADDRESS) {
1028
snmp_log(LOG_ERR, "not IP Address\n");
1029
return SNMP_ERR_WRONGTYPE;
1031
if ((*((int *) var_val)) < 0) {
1032
snmp_log(LOG_ERR, "invalid media net address");
1033
return SNMP_ERR_WRONGVALUE;
1035
if (var_val_len > sizeof(DWORD)) {
1036
snmp_log(LOG_ERR, "bad length\n");
1037
return SNMP_ERR_WRONGLENGTH;
1041
if (var_val_type != ASN_INTEGER) {
1042
snmp_log(LOG_ERR, "not integer\n");
1043
return SNMP_ERR_WRONGTYPE;
1045
if ((*((int *) var_val)) < 1 || (*((int *) var_val)) > 4) {
1046
snmp_log(LOG_ERR, "invalid media type");
1047
return SNMP_ERR_WRONGVALUE;
1049
if (var_val_len > sizeof(int)) {
1050
snmp_log(LOG_ERR, "bad length\n");
1051
return SNMP_ERR_WRONGLENGTH;
1054
case IPMEDIAPHYSADDRESS:
1055
if (var_val_type != ASN_OCTET_STR) {
1056
snmp_log(LOG_ERR, "not octet str");
1057
return SNMP_ERR_WRONGTYPE;
1059
if (var_val_len != 6) {
1060
snmp_log(LOG_ERR, "not correct ipAddress length: %d",
1062
return SNMP_ERR_WRONGLENGTH;
1066
DEBUGMSGTL(("snmpd", "unknown sub-id %d in write_rte\n",
1068
return SNMP_ERR_NOTWRITABLE;
1073
* Save the old value, in case of UNDO
1075
if (oldarp_row == NULL) {
1076
oldarp_row = (PMIB_IPNETROW) malloc(sizeof(MIB_IPNETROW));
1077
*oldarp_row = *arp_row;
1080
case ACTION: /* Perform the SET action (if reversible) */
1083
case IPMEDIAIFINDEX:
1084
temp_row = *arp_row;
1085
arp_row->dwIndex = *((int *) var_val);
1087
* In case of new entry, physical address is mandatory.
1088
* * SetIpNetEntry will be done in COMMIT case
1091
if (SetIpNetEntry(arp_row) != NO_ERROR) {
1092
arp_row->dwIndex = temp_row.dwIndex;
1093
retval = SNMP_ERR_COMMITFAILED;
1096
* Don't know yet, whether change in ifIndex creates new row or not
1102
* temp_row.dwType = 2;
1105
* if(SetIpNetEntry(&temp_row) != NO_ERROR)
1108
* retval = SNMP_ERR_COMMITFAILED;
1115
case IPMEDIANETADDRESS:
1116
temp_row = *arp_row;
1117
arp_row->dwAddr = *((int *) var_val);
1119
if (SetIpNetEntry(arp_row) != NO_ERROR) {
1120
arp_row->dwAddr = oldarp_row->dwAddr;
1121
retval = SNMP_ERR_COMMITFAILED;
1123
temp_row.dwType = 2;
1124
if (SetIpNetEntry(&temp_row) != NO_ERROR) {
1126
"Failed in ACTION, while deleting old row \n");
1127
retval = SNMP_ERR_COMMITFAILED;
1133
arp_row->dwType = *((int *) var_val);
1135
if (SetIpNetEntry(arp_row) != NO_ERROR)
1136
retval = SNMP_ERR_COMMITFAILED;
1139
case IPMEDIAPHYSADDRESS:
1140
memcpy(arp_row->bPhysAddr, var_val, var_val_len);
1141
arp_row->dwPhysAddrLen = var_val_len;
1143
if (SetIpNetEntry(arp_row) != NO_ERROR)
1144
retval = SNMP_ERR_COMMITFAILED;
1148
DEBUGMSGTL(("snmpd", "unknown sub-id %d in write_arp\n",
1150
retval = SNMP_ERR_NOTWRITABLE;
1155
* Reverse the SET action and free resources
1157
if (oldarp_row != NULL) {
1159
* UNDO the changes done for existing entry.
1162
if ((status = SetIpNetEntry(oldarp_row)) != NO_ERROR) {
1163
snmp_log(LOG_ERR, "Error in case UNDO, status : %d\n",
1165
retval = SNMP_ERR_UNDOFAILED;
1169
if (oldarp_row->dwAddr != arp_row->dwAddr) {
1170
arp_row->dwType = 2; /*If row was added/created delete that row */
1172
if ((status = SetIpNetEntry(arp_row)) != NO_ERROR) {
1174
"Error while deleting added row, status : %d\n",
1176
retval = SNMP_ERR_UNDOFAILED;
1188
* if new entry and physical address specified, create new entry
1191
if (arp_row->dwPhysAddrLen != 0) {
1192
if ((status = CreateIpNetEntry(arp_row)) != NO_ERROR) {
1194
"Inside COMMIT: CreateIpNetEntry failed, status %d\n",
1196
retval = SNMP_ERR_COMMITFAILED;
1200
* For new entry, physical address must be set.
1203
"Can't create new entry without physical address\n");
1204
retval = SNMP_ERR_WRONGVALUE;
1207
* unset the create_flag, so that CreateIpNetEntry called only once
1214
* Free any resources allocated